1

这不是我如何在 Java 中编写正确的微基准测试的副本?

问题涉及 Project Loom 设计和实现的核心,以及该项目是否能够加速 Java Parallel Streams 的性能。问题不在于基准测试,而在于 Project Loom 的意图。


我正在我的loom-lab项目中试验虚拟线程,并想看看在执行并行流时虚拟线程是否比平台线程快,但实际上它似乎更慢。

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 集成?

4

1 回答 1

1

好吧,我的感觉是

IIUC,虚拟线程的真正好处是当您进行阻塞 I/O 操作时。使用 Loom,底层载体线程将在您的虚拟线程阻塞时继续执行其他任务。在 Loom 之前,没有进行这种区分——只有一种类型的线程——阻塞 I/O 对于高吞吐量应用程序(如 Web 服务器)来说不是一个可行的选择。

意味着在这个用例中,虚拟线程不会给我带来我希望的性能提升......

在我的实验中,我正在计算素数

  1. 7397 毫秒 - 顺序流
  2. 1316 毫秒 - 并行流
  3. 1392 毫秒 - 具有虚拟线程的执行服务上下文中的并行流
  4. 4472 毫秒 - 虚拟线程executorService.invokeAll(tasks)
  5. 4338 毫秒 - 从流创建的虚拟线程

案例 2 和 3 的性能非常接近,它们在误差范围内。

这不是 I/O 限制,它纯粹是计算限制。在这种情况下,Parallel Streams 工作得非常好,而且很难(不可能?)做得更好。我期望我可以使用虚拟线程加快速度是对虚拟线程如何优化的误解。现在我知道得更清楚了。

如果我想展示虚拟线程相对于平台线程的性能优势,我需要找到一个更好的用例。

我的代码发布在loom-lab上,以防其他人想要验证我的结论。这是一个学习项目,我正在学习...

于 2021-11-04T00:08:36.837 回答