Глядя на ваш пример кода, я догадываюсь, что вы переходите прямо в основной метод из командной строки. Это самый худший способ, которым вы можете заниматься микропрофилированием в Java!
Сначала вы должны запустить тест несколько раз (в пределах одного и того же вызова виртуальной машины), по крайней мере, настолько, чтобы JVM правильно прогревался и работал в течение добрых 30 секунд, прежде чем вы даже думаете о том, чтобы начать что-либо измерять. Это обеспечит выполнение скомпилированного (а не интерпретированного) кода и его полную оптимизацию.
Вам также необходимо знать стоимость запуска потоков. Для кратковременных циклов это будет непомерно высоким и потребует больше времени, чем сам цикл!
обновление
Следующие определения взяты из ops.scala:
val defaultRunner: FutureTaskRunner = TaskRunners.threadRunner
def spawn(p: => Unit)(implicit runner: TaskRunner = defaultRunner): Unit = {...}
def replicate(start: Int, end: Int)(p: Int => Unit) {...}
Таким образом, фактически используемый бегун вводится как неявный,
или по умолчанию TaskRunners.threadRunner
Вы можете попытаться изменить это, чтобы использовать пул потоков, добавив префикс вашего кода:
implicit val runner = TaskRunners.threadPoolRunner
Или я верю следующее тоже будет работать:
import concurrent.TaskRunners.threadPoolRunner
Посмотрите, имеет ли это значение
На второй мысли ...
Я не думаю, что этот параметр на самом деле будет передаваться вложенному вызову spawn
, вероятно, лучше, если вы просто продублируете метод самостоятельно (у меня в настоящее время есть запрос об этом, опубликованный в списках рассылки).
Для вашего удобства вот метод в полной, ужасающей славе:
def replicate(start: Int, end: Int)(p: Int => Unit) {
if (start == end)
()
else if (start + 1 == end)
p(start)
else {
val mid = (start + end) / 2
spawn { replicate(start, mid)(p) }
replicate(mid, end)(p)
}
}
(вам все еще нужно определить неявного бегуна ...)