{"id":3951,"date":"2015-06-17T13:00:31","date_gmt":"2015-06-17T13:00:31","guid":{"rendered":"http:\/\/writeasync.net\/?p=3951"},"modified":"2015-06-17T05:21:46","modified_gmt":"2015-06-17T05:21:46","slug":"continuewith-slowly","status":"publish","type":"post","link":"http:\/\/writeasync.net\/?p=3951","title":{"rendered":"ContinueWith slowly"},"content":{"rendered":"<p>Previously I discussed <a href=\"http:\/\/writeasync.net\/?p=2371\">the hidden costs of &#8216;async&#8217;<\/a> and even discussed a benchmark within <a href=\"http:\/\/writeasync.net\/?p=2371#comment-1571\">the comments<\/a>. Here is another interesting benchmark on a case that I&#8217;ve seen come up a few times. Which of these do you think is faster?<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n\/\/ Option A: use 'async' + 'await'\r\nprivate static async Task&lt;long&gt; GetNumberAAsync()\r\n{\r\n    long value = await GetNumberAsync();\r\n    return value + 1;\r\n}\r\n\r\n\/\/ Option B: use 'ContinueWith'\r\nprivate static Task&lt;long&gt; GetNumberBAsync()\r\n{\r\n    return GetNumberAsync().ContinueWith(t =&gt; t.Result + 1, TaskContinuationOptions.ExecuteSynchronously);\r\n}\r\n\r\n\/\/ (Inner function to do some trivial async work)\r\nprivate static async Task&lt;long&gt; GetNumberAsync()\r\n{\r\n    await Task.Yield();\r\n    return Stopwatch.GetTimestamp();\r\n}\r\n<\/pre>\n<p>If you had to take a wild guess, maybe you&#8217;d say option B because it doesn&#8217;t have the &#8220;baggage&#8221; of the internal <a href=\"https:\/\/www.simple-talk.com\/dotnet\/.net-tools\/c-async-what-is-it,-and-how-does-it-work\/\">async state machine<\/a>. But when I measured, I got these results:<br \/>\n<div id=\"attachment_3961\" style=\"width: 310px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/writeasync.net\/wp-content\/uploads\/2015\/06\/AwaitVsContinueWith.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3961\" src=\"http:\/\/writeasync.net\/wp-content\/uploads\/2015\/06\/AwaitVsContinueWith-300x180.png\" alt=\"Await (A) vs. ContinueWith (B)\" width=\"300\" height=\"180\" class=\"size-medium wp-image-3961\" srcset=\"http:\/\/writeasync.net\/wp-content\/uploads\/2015\/06\/AwaitVsContinueWith-300x180.png 300w, http:\/\/writeasync.net\/wp-content\/uploads\/2015\/06\/AwaitVsContinueWith.png 480w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-3961\" class=\"wp-caption-text\">Await (A) vs. ContinueWith (B)<\/p><\/div><br \/>\nThis is 100 data points for each benchmark arranged in sorted order. The vertical axis is <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/system.datetime.ticks(v=vs.110).aspx\">ticks<\/a> per iteration, so higher is worse. Surprisingly, the data from my experiment showed that option A (&#8216;async&#8217; + &#8216;await&#8217;) is slightly faster on the whole.<\/p>\n<p>Why is this? It could be that the ContinueWith path is not as heavily optimized as the generated asynchronous code. If you decompile an &#8216;async&#8217; function, you will note that ContinueWith is in fact <em>not<\/em> used in the resulting code, but rather <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/hh472363(v=vs.110).aspx\"><code>AwaitUnsafeOnCompleted<\/code><\/a>.<\/p>\n<p>Then again, let&#8217;s put this in perspective. Spending an extra 100 <em>nanoseconds<\/em> on average is eminently negligible. Your optimization energy is probably better spent elsewhere. Still, it&#8217;s good to know that there&#8217;s no shame in using &#8216;async&#8217; &#8212; on the contrary, there are some perf gains to be won here.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Previously I discussed the hidden costs of &#8216;async&#8217; and even discussed a benchmark within the comments. Here is another interesting benchmark on a case that I&#8217;ve seen come up a few times. Which of these do you think is faster?&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21],"tags":[],"class_list":["post-3951","post","type-post","status-publish","format-standard","hentry","category-async"],"_links":{"self":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/3951","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3951"}],"version-history":[{"count":0,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/3951\/revisions"}],"wp:attachment":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3951"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3951"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3951"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}