我通过创建一个简单的循环并在数组中添加元素来测试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(&#34; java.util.concurrent.ForkJoinPool.common.parallelism&#34 ;, &#34; 1&#34);
但CPU使用率仍然很高。
还建议使用并行流吗?因为在我的应用程序中假设我有10个用户线程,或者每个请求都是一个线程的Web应用程序,在这种情况下如果我在多个线程上启动并行流最终吃我所有的cpu,都会有这么多的上下文切换。
答案 0 :(得分:2)
我的0.02 $:huge performance boost over non parallel one
。 巨大的在这里可能有点太多了。这可能是有充分理由的 - 首先是你测试的方式。至关重要的是,有一个问题,超过500票,特别是对此:micro-benchmark。您可能认为您已经编写了良好的测试,但jvm可能会为您制定不同的计划。
对于中等数据,实际上顺序流可能比并行流更快。必须通过并行流完成更多工作。但如果没有实际测量,几乎不可能说出来;但这里有来自该领域最佳的推荐,如this。
当你说你想要将java限制在一些核心时 - 简单的答案就是你不能;来自java代码。必须从OS
完成,如果可行的话。通过java.util.concurrent.ForkJoinPool.common.parallelism
启用的功能是限制线程,而不是核心。
单个线程可以分割为多个cpus - 它取决于操作系统本身。
答案 1 :(得分:1)
默认情况下,并行流在系统范围内的ForkJoinPool中运行,它为您机器上的每个核心提供一个线程。
如果您想更改此行为,可以在您选择的ForkJoinPool中运行并行流:
ForkJoinPool fjp = new ForkJoinPool(2);
ForkJoinTask<Long> sumFuture = fjp.submit(() -> {
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();
}
return sum;
});