Улучшит ли Project Loom Virtual Threads производительность параллельных потоков?

Это не дубликат статьи " Как написать правильный микротест на Java?"

Вопрос лежит в основе разработки и реализации Project Loom, а также в том, смог ли проект повысить производительность параллельных потоков Java или нет. Вопрос не в тестировании производительности, а в намерениях Project Loom.


Я экспериментирую с виртуальными потоками в своем проекте лаборатории ткацкого станка и хотел посмотреть, работают ли виртуальные потоки быстрее, чем потоки платформы при выполнении параллельного потока, но на самом деле это кажется медленнее.

      try (var executorService = Executors.newThreadPerTaskExecutor(virtualThreadFactory)) {
    var candidates3 = LongStream.iterate(3, x -> x < count, x -> x + 2);
    time4 = System.currentTimeMillis();
    var primes3 = executorService.submit(() ->
        candidates3.parallel()
            .filter(candidate -> isPrime(candidate)).toArray()
    ).get();
    time5 = System.currentTimeMillis();
}

где в конечном итоге я получаю результат (в миллисекундах)

      sequential time = 7546
parallel   time = 1289
virtual    time = 1388

и в целом использование виртуальных потоков медленнее, чем обычный ForkJoinPool. Допускаю ли я какую-то основную ошибку или недоразумение, или Project Loom еще не интегрирован с Java Streams?

1 ответ

Решение

Хорошо, я чувствую, что

IIUC, реальное преимущество виртуального потока - это когда у вас есть блокирующая операция ввода-вывода. С Loom основной поток-носитель будет продолжать выполнять другие задачи, пока ваш виртуальный поток блокируется. До Loom это различие не проводилось - был только один тип потоков - и блокирующий ввод-вывод не подходил для приложений с высокой пропускной способностью, таких как веб-серверы.

означает, что виртуальные потоки не дадут мне повышения производительности, на которое я надеялся в этом случае использования ...

В моем эксперименте я вычислял простые числа с помощью

  1. 7397 мс - последовательный поток
  2. 1316 мс - параллельный поток
  3. 1392 мс - параллельный поток в контексте службы выполнения с виртуальными потоками
  4. 4472 мс - виртуальные потоки с executorService.invokeAll(tasks)
  5. 4338 мс - виртуальные потоки, созданные из потока

Варианты 2 и 3 настолько близки по характеристикам, что находятся в пределах погрешности.

Это не ограничение ввода-вывода, это чисто вычислительное ограничение. В этом случае параллельные потоки работают исключительно хорошо, и трудно (невозможно?) Добиться большего. Мое ожидание, что я смогу ускорить процесс с помощью виртуальных потоков, было неправильным пониманием того, как оптимизировать виртуальные потоки. Теперь я знаю лучше.

Если я хочу продемонстрировать преимущество виртуальных потоков в производительности над потоками платформы, мне нужно найти лучший вариант использования.

Мой код размещен в loom-lab на случай, если другие люди захотят проверить мои выводы. Это обучающий проект, и я учусь ...

Другие вопросы по тегам