|
|
|
|
|
by pron
1770 days ago
|
|
1. CPU-bound problems that are not externally driven by I/O events fall under the purview of parallelism (shortening the latency of performing a single task by splitting it into cooperating tasks that employ multiple processing units) rather than concurrency (increasing the throughput of handling multiple competing, largely independent events, using scheduling). In Java, parallel streams and the low-level ForkJoinTask were made to address parallelism, whereas Loom's virtual threads are designed to tackle concurrency. It is true that some parallel use-cases are more conveniently expressed with continuations, but more on that below. 2. For CPU-bound workloads, virtually any overhead that isn't zero can come to dominate in many situations. The overhead can be made to be zero when the tasks are known in advance and can be inlined. This happens in two situations: generators, where there is one producer that can be inlined together with the consumer, and parallel workloads where all the tasks are the same. I am not aware of any single implementation, or even a single user-facing construct, that gives you the optimal experience both in those situations and in I/O-driven concurrency. If you have only one continuation construct, you must choose whether you want to favour one or the other. C++ favours the former, while Java, like Go, the latter, partly because Java already has a decent parallelism construct, and partly because we believe that the concurrent use-case delivers more value to more people. If parallel use-cases that benefit from continuations and/or generators come in high demand, we can address them later. |
|