我通过创建一个简单的循环并在数组中添加元素来测试 java 8 并行流 api 的性能。
与非并行相比,我的性能得到了巨大的提升。
但是当我检查任务管理器时,我发现 CPU 使用情况不受控制,它在此期间耗尽了我的所有 CPU。
这是我的示例代码,
public static void withIfElse(boolean sorted) {
int[] arr = new int[32768];
Random rand = new Random();
for(int i = 0;i < arr.length;i++)
arr[i] = rand.nextInt(256);
if(sorted)
Arrays.parallelSort(arr);
long nst = System.currentTimeMillis();
long sum = 0;
for(int j=0;j<100000;j++) {
sum += Arrays.stream(arr).parallel().filter(m->m>=128).reduce((m,n)-> m+n).getAsInt();
}
System.out.printf("Time taken for boolean %b is %d ms. \n",sorted,(System.currentTimeMillis()-nst));
}
我能够实现近 2 倍到 8 倍的性能提升。
但是,
CPU 使用不受控制。有没有办法强制java只有2个核心?
我也尝试过设置
System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "1");
但 CPU 使用率仍然很高。
还建议使用并行流吗?因为假设在我的应用程序中我有 10 个用户线程,或者一个 Web 应用程序,其中每个请求都是一个线程,在这种情况下,如果我在多个线程上启动并行流,最终会吃掉我所有的cpu,都会有这么多的上下文切换。
最佳答案
我的 0.02 美元:比非并行的性能大幅提升
。 巨大在这里可能有点太多了。这可能有充分的理由——首先,你的测试方式。这是非常重要的,以至于有一个问题有超过 500 个赞成票,特别是为此:micro-benchmark 。您可能认为您编写了很好的测试,但 jvm 可能为您制定了不同的计划。
对于中等数据,顺序流确实可能比并行流更快。并行流必须完成更多的工作。但如果没有实际测量,这几乎是不可能说的;但这里有来自该领域最优秀的人的建议,例如 this .
当你说你想将 java 限制在某些核心上时 - 简单的答案是你不能;来自java代码。如果可行的话,它必须从操作系统完成。您通过 java.util.concurrent.ForkJoinPool.common.parallelism 启用的功能是限制线程,而不是核心。
单个线程可以拆分到多个 cpu 上 - 这取决于操作系统本身。
关于java - 限制java8并行流的CPU使用率/Java 8并行流的高CPU使用率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44608168/