Hi, thanks for looking into this! First, let me comment on a few points you’ve mentioned:

  • “The example uses a kind of anti-pattern for async usage in C#” — that’s true, and I’ve mentioned it’s an unfair benchmark for C#. I intentionally took a well-known benchmark for goroutines knowing it’s highly disadvantageous for C# to demonstrate that async/await should be comparable even in this case in terms of performance.

Finally, performance isn’t the only focus point in this article. I mostly wanted to show how these languages differ in terms of their approach to asynchronous computation, and obviously, you can’t do this w/o such benchmarks.

No matter what, thanks a lot for quite useful feedback!

P.S. If you don’t mind, I’d love to reference your post if I’ll decide to publish another post on async/await vs Go here. I plan to do this closer to .NET Core 2.1 release — likely, with more benchmarks in general. Based on what’s known so far, we should expect pretty dramatic improvements in speed for C# with this release.

P.P.S. The funny part is: I actually spent some time to find out why missing tail / prologue Task.Yield() triggers recursion in this example. And my original plan for that post was to share stack traces to show where exactly it happens, why it happens, and why this optimization in TPL actually makes a lot of sense. But I ended up explaining only the side effect of that and cut the rest — solely because of a lack of time. And now I see why it looks like I didn’t dig deeply enough into why it happens, esp. taking into account the title. So maybe it’s a good lesson for my future posts :)



Creator of https://github.com/servicetitan/Stl.Fusion , ex-CTO @ ServiceTitan.com

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store