10 ms·
C# .NET had async and await in 2012, for comparison. I've always loved Java but Microsoft deserves immense credit for raising the bar, and so quickly, too.
by vijucat 4y ago
C# .NET had async and await in 2012, for comparison. I've always loved Java but Microsoft deserves immense credit for raising the bar, and so quickly, too.
- VagueMag 4y agoAt least from the Java language advocates' perspective, async/await is a worse solution to the problem of async than the structured concurrency approach that virtual threads will enable.
- andrekandre 4y agothats interesting, any good examples?
- VagueMag 4y agoTons of writing and debate on this subject but the canonical starting point is "What Color Is Your Function?" https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/ https://journal.stuffwithstuff.com/2015/02/01/what-color-is-...
- cyberax 4y agoAsync/await are also much slower than properly implemented (see: Golang) fibers. Basically, with async/await you need to allocate on the heap frames for each level of the async/await call stack. You basically get a linked list of stack frames. This is essentially isomorphic to segmented stacks that Go ditched in favor of resizable stacks, because segmented stacks kill performance if a tight loop just happens to cross a segment boundary.
- DeathArrow 4y ago>Async/await are also much slower than properly implemented (see: Golang) fibers. Are there any benchmarks to back that affirmation?
- cyberax 4y agoHm. I know this from my personal work, replacing Go code with an async/await code. There's a bunch of benchmarks that compare C# async/await and Goroutines (e.g. https://alexyakunin.medium.com/go-vs-c-part-1-goroutines-vs-async-await-ac909c651c11 https://alexyakunin.medium.com/go-vs-c-part-1-goroutines-vs-... ). Go still wins there, but they all miss the very important case of nested async/awaits. These microbenchmarks also focus on looking at Go channels versus other synchronization methods, which in my experience is not that relevant (Go channels just suck). I guess I'll need to write a blog post.
- DeathArrow 4y agoThose benchmarks are really old, things can change quite fast when it comes to programming language implementations.
- cyberax 4y agoI wrote a quick-and-dirty benchmark: https://blog.alex.net/benchmarking-go-and-c-async-await https://blog.alex.net/benchmarking-go-and-c-async-await Results: Go - 32ms, C# - 494ms. The difference also becomes bigger as you add more recursion levels.
- dgb23 4y agoAsync/await proliferates. If you call await, your function must be async too. Green threads are decoupled from synchronization.
- DeathArrow 4y agoYou can use tasks without async/await.
- DeathArrow 4y agoasync/wait is using tasks which are the equivalent of virtual threads. What I do like to see in C# is something akin to goroutines from Go or actors in Elixir.
- shellac 4y agoThis response confuses me since goroutines and Erlang processes are really very similar to project Loom's virtual threads. The mistake is that async/await is not equivalent to virtual threads: the former can do only a subset of what the latter can.
- guiriduro 4y agoVirtual actors for C# are offered by solutions like MS Orleans as I understand it.
- masklinn 4y ago> What I do like to see in C# is something akin to goroutines from Go or actors in Elixir. A task is equivalent to a goroutine.
- DeathArrow 4y agoNot really, see: http://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/ http://journal.stuffwithstuff.com/2015/02/01/what-color-is-y... https://alexyakunin.medium.com/go-vs-c-part-1-goroutines-vs-async-await-ac909c651c11 https://alexyakunin.medium.com/go-vs-c-part-1-goroutines-vs-... https://stackoverflow.com/questions/70501171/are-golang-goroutines-relatively-the-same-as-c-sharp-tasks https://stackoverflow.com/questions/70501171/are-golang-goro...
- dopidopHN 4y agoMy understanding is that green threads are different on the implementation side as well. Basically they are cheaper at the system level? The API do not even change much last time I checked. It’s all happening in how the JVM span threads
- seabrookmx 4y agoThat head start has had a huge impact on the ecosystem too. Random libraries (ex: Google.Cloud.PubSub.V1) have first class, mature support for async and streams. Compare that to Python (and I'd have to assume Python is much more popular on Google Cloud) which only recently got async support and it's still kludgy. This really applies across the board for anything web related. JavaScript/TypeScript is probably the only ecosystem with comparable async support, unless you count golang which achieves a similar result with different ergonomics. I'm still on the fence on which I personally prefer.. I can see the appeal of not having the async logic pollute the callstack, but at the same time the magic[1] way golang handles i/o seems antithetical to its philosophy of being simple and explicit (for example, with respect to error handling). [1]: https://www.reddit.com/r/golang/comments/xiu4zg/comment/ip77rg1 https://www.reddit.com/r/golang/comments/xiu4zg/comment/ip77...
- capableweb 4y agoJava Virtual Threads seems to be a ("better" in their mind) alternative than async/await, so not sure Microsoft should be credited for Java Virtual Threads? > Also, the async/await approach, such as Kotlin coroutines, has its own problems. Even though it aims to model the one task per thread approach, it can’t rely on any native JVM construct. For example, Kotlin coroutines based the whole story on suspending functions, i.e., functions that can suspend a coroutine. However, the suspension is wholly based upon non-blocking IO, which we can achieve using libraries based on Netty, but not every task can be expressed in terms of non-blocking IO. Ultimately, we must divide our program into two parts: one based on non-blocking IO (suspending functions) and one that does not. This is a challenging task; it takes work to do it correctly. Moreover, we lose again the simplicity we want in our programs. > The above are reasons why the JVM community is looking for a better way to write concurrent programs. Project Loom is one of the attempts to solve the problem. So, let’s introduce the first brick of the project: virtual threads.
- jayd16 4y agoIt's not really an alternative to async/await. Implicit vs cooperative multithreading have pros and cons for each.
- capableweb 4y agoAuthors of Loom seems to disagree with you. > An alternative solution to that of fibers to concurrency's simplicity vs. performance issue is known as async/await, and has been adopted by C# and Node.js, and will likely be adopted by standard JavaScript. Continuations and fibers dominate async/await in the sense that async/await is easily implemented with continuations (in fact, it can be implemented with a weak form of delimited continuations known as stackless continuations, that don't capture an entire call-stack but only the local context of a single subroutine), but not vice-versa. > While implementing async/await is easier than full-blown continuations and fibers, that solution falls far too short of addressing the problem. While async/await makes code simpler and gives it the appearance of normal, sequential code, like asynchronous code it still requires significant changes to existing code, explicit support in libraries, and does not interoperate well with synchronous code. In other words, it does not solve what's known as the "colored function" problem. This is under the section called "Other Approaches" in https://cr.openjdk.org/~rpressler/loom/Loom-Proposal.html https://cr.openjdk.org/~rpressler/loom/Loom-Proposal.html That seems to indicate to me that async/await would be an alternative to virtual threads.
- thatnerdyguy 4y agoAnd they are experimenting with green threads now. Would be... hilarious? If it landed in .NET before Java. https://github.com/dotnet/runtimelab/tree/feature/green-threads https://github.com/dotnet/runtimelab/tree/feature/green-thre...
- geodel 4y agoIn Java it is landed already as preview feature last September and will be final feature this September.
- pkulak 4y agoThis is way better than async/await. This is Go/Erlang levels of green thread ease of use.
- metaltyphoon 4y agoI guess everyone is entitled to their opinion.
- riku_iki 4y ago> .NET had async and await in 2012, for comparison. java had ExecutorService and futures support for a while, it is just another synthetic sugar around the same solution, although Java's approach is much more powerful and flexible.
- kitd 4y agoJava had green threads in v1.0.
- DeathArrow 4y agoNot only async, but C# had LINQ, lambdas, records, pattern matching, pointers, hardware instructions via intrinsics, stackalloc etc. before similar constructs came into Java, if they ever did. Probably there are examples where Java introduced something first, but I don't know because I'm not so well versed in Java. While similar and inspired by Java, I do prefer C# because is less verbose, requires less boiler plate, it generally has only one proper way to do things and is kind of jack of all trades, in the sense you can tackle any area of programming besides very low level systems programming - and It quite can reach that point, too if there will be a way to disable GC and allow manual memory management. Web backend - check, web frontend - check, mobile apps - check, desktop - check, multi platform - check, embedded - check, games - check, VM - check, native AOT - check. It also looks great in benchmarks: https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/csharp.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/... I am biased but since I recognize it, maybe you shouldn't downvote me just for that. :) And what's even better than C# is F#, but that's too bad nobody likes functional programming or hire programmers to use functional languages.
- krzyk 4y ago> Not only async, but C# had LINQ, lambdas, records, pattern matching, pointers, hardware instructions via intrinsics, stackalloc etc. before similar constructs came into Java, if they ever did. Just a clarification regarding one statement which I know for sure is not true: Java team started working on records before C# started similar work. I don't know about the rest.
- shellac 4y agoAnd pattern matching was started in java first (goes hand-in-hand with records to some extent).
- pron 4y agoThere's plenty of stuff Java did first (or only) -- an optimising JIT, two new generations of GC (G1, ZGC--a low latency GC with <1ms max pause time), low-overhead deep profiling (Java Flight Recorder) -- but they're all in the runtime. Java's strategy since the beginning has always been to innovate on the platform and be a last-mover on the language, keeping it conservative. .NET seems to follow an opposite strategy. That's how we've been able to avoid properties and just have algebraic data types, avoid async/await and do virtual threads, avoid string interpolation and just have safe string templates. This also allows us to keep the number of features in the language relatively low -- as we, and most of our users, like it.