8
实验:ForkJoinPool 并行度
source link: https://lotabout.me/2020/Benchmark-ForkJoinPool/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
实验:ForkJoinPool 并行度
Table of Contents
在调用外部接口时通过 CompletableFuture.supplyAsync
异步调用,该方法默认将任务提交到全局唯一的 ForkJoinPool,而它的并行度可以受
java.util.concurrent.ForkJoinPool.common.parallelism
影响。
本实验的目的是探究在异步请求快响应(~= 1ms)时,并行度对整体性能的影响。
真实场景:
- 每次请求约调用接口 200 次
- 每次接口请求约 1ms 完成
当然由于接受并发请求,同时会接收多个请求,暂不纳入考虑。bench 代码如下:
List<Future> futures = new ArrayList<>();
for(int i=0; i<N; i++) {
final int x = i;
futures.add(CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
bh.consume(x);
return x;
}));
}
for (Future future: futures) {
future.get();
}
- OS: Mac, 8C, 16G
- Java version: JDK 11.0.2, OpenJDK 64-Bit Server VM, 11.0.2+9
- Bench 框架:JMH
- JMH 调用参数:
java -jar target/benchmarks.jar -i 5 -bs 50 -f 3
实验结果如下图:
- 图中的并行度分别为 1, 2, 4, 8, 16, 32, 64, 128, 256
- 图中的 x 轴间隔是 log 过后的结果,可以看到两点的 x 轴距离相等
- 最左边的点
parallelism = 1
时,ForkJoinPool 会为每个提交的任务创建一个线程 - 第二个点代表
parallelism = 2
,此时最多运行两个线程,预期的时间为1 * 200 50 / 2 = 5000ms
实际开销6610
,多出的猜测是线程创建和切换 - 并行度翻倍后,平均时间大概减少一半,但随着并行度的增大(>8),减少的时间慢慢就小于一半了。
- 最后即使
parallelism > 200
,也没办法达到完全并行(1ms)的状态。
大致结论:并行度越大效果越好,但 overhead 也会越来越大。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK