gpt4 book ai didi

java - ExecutorService 多线程性能低

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:46:12 24 4
gpt4 key购买 nike

我正在尝试执行一个简单的计算(它调用 Math.random() 10000000 次)。令人惊讶的是,以简单的方法运行它比使用 ExecutorService 执行得更快。

我在 ExecutorService's surprising performance break-even point --- rules of thumb? 阅读了另一个主题并尝试通过使用批处理执行 Callable 来跟踪答案,但性能仍然很差

如何根据我当前的代码提高性能?

import java.util.*;
import java.util.concurrent.*;

public class MainTest {
public static void main(String[]args) throws Exception {
new MainTest().start();;
}

final List<Worker> workermulti = new ArrayList<Worker>();
final List<Worker> workersingle = new ArrayList<Worker>();
final int count=10000000;

public void start() throws Exception {
int n=2;

workersingle.add(new Worker(1));
for (int i=0;i<n;i++) {
// worker will only do count/n job
workermulti.add(new Worker(n));
}

ExecutorService serviceSingle = Executors.newSingleThreadExecutor();
ExecutorService serviceMulti = Executors.newFixedThreadPool(n);
long s,e;
int tests=10;
List<Long> simple = new ArrayList<Long>();
List<Long> single = new ArrayList<Long>();
List<Long> multi = new ArrayList<Long>();

for (int i=0;i<tests;i++) {
// simple
s = System.currentTimeMillis();
simple();
e = System.currentTimeMillis();
simple.add(e-s);

// single thread
s = System.currentTimeMillis();
serviceSingle.invokeAll(workersingle); // single thread
e = System.currentTimeMillis();
single.add(e-s);

// multi thread
s = System.currentTimeMillis();
serviceMulti.invokeAll(workermulti);
e = System.currentTimeMillis();
multi.add(e-s);
}
long avgSimple=sum(simple)/tests;
long avgSingle=sum(single)/tests;
long avgMulti=sum(multi)/tests;
System.out.println("Average simple: "+avgSimple+" ms");
System.out.println("Average single thread: "+avgSingle+" ms");
System.out.println("Average multi thread: "+avgMulti+" ms");

serviceSingle.shutdown();
serviceMulti.shutdown();
}

long sum(List<Long> list) {
long sum=0;
for (long l : list) {
sum+=l;
}
return sum;
}

private void simple() {
for (int i=0;i<count;i++){
Math.random();
}
}

class Worker implements Callable<Void> {
int n;

public Worker(int n) {
this.n=n;
}

@Override
public Void call() throws Exception {
// divide count with n to perform batch execution
for (int i=0;i<(count/n);i++) {
Math.random();
}
return null;
}
}
}

这段代码的输出

Average simple: 920 ms
Average single thread: 1034 ms
Average multi thread: 1393 ms

编辑:由于 Math.random() 是同步方法,性能受到影响。在为每个线程使用新的 Random 对象更改 Math.random() 后,性能得到改善

新代码的输出(在将每个线程的 Math.random() 替换为 Random 之后)

Average simple: 928 ms
Average single thread: 1046 ms
Average multi thread: 642 ms

最佳答案

Math.random()是同步的。 synchronized 的全部意义在于减慢速度,以免它们发生冲突。使用不同步的东西和/或给每个线程自己的对象来处理,比如一个新的 Random .

关于java - ExecutorService 多线程性能低,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7155608/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com