Why does Scala use a ForkJoinPool to back its default ExecutionContext?
Asked Answered
C

1

29

In Scala you can use a global ExecutionContext if you don't need to define your own by importing scala.concurrent.ExecutionContext.Implicits.global.

My question is why ForkJoinPool was chosen for this executor instead of ThreadPoolExecutor.

My understanding is that the fork-join framework is excellent at recursively decomposing problems. You're supposed to write code that breaks a task into halves, so that half can be executed in-thread and the other half can be executed by another thread. This seems like a very particular programming model and not one that would be generally applicable to handling execution of general asynchronous tasks across a wide range of possible applications.

So why was ForkJoinPool chosen for the default execution context that most people will likely use? Does the work-stealing design result in improved performance even if you don't use the full fork-join paradigm?

Carpetbag answered 17/7, 2015 at 1:11 Comment(1)
A
5

I can't speak for the scala designers, but idiomatic use of scala Futures often involves creation of a lot of very small, short-lived tasks (e.g. every map call creates a new task) and so the work-stealing design is appropriate.

If you care about these kind of precise details you might prefer to use scalaz-concurrent's Future, which uses trampolines to avoid creating extra tasks for each map step and makes execution contexts explicit (and AIUI defaults to a ThreadPoolExecutor).

Ardie answered 17/7, 2015 at 9:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.