25

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?

Brian Gordon
  • 5,993
  • 2
  • 28
  • 37

1 Answers1

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).

lmm
  • 17,076
  • 3
  • 23
  • 37