我正在尝试减少循环的执行时间,主要包括读取列表中的数据,对其进行一些计算以及将结果写入数组。
我在四核CPU上的200万个元素列表上尝试这些测试:
似乎单个线程比4个线程快(我也试过2个)。
我想知道为什么???我认为问题在于I / O吞吐量,但是我很沮丧地将处理器用于25%并等待计算。
是否有任何改进/并行化列表迭代的解决方案?
记忆是限制因素吗?
编辑:已添加代码
public class Main {
public static void main(String[] args) {
List<Integer> li = new ArrayList<Integer>();
IntStream.rangeClosed(1, 20_000_000).forEach(i -> li.add(i));
Integer[] tab = new Integer[1000];
IntStream.rangeClosed(0, 999).forEach(i -> tab[i] = 0);
System.out.println("debut");
Long start = System.currentTimeMillis();
Thread t1 = new Thread(new ThreadRunner(li, tab, 1, 0));
Thread t2 = new Thread(new ThreadRunner(li, tab, 4, 1));
Thread t3 = new Thread(new ThreadRunner(li, tab, 4, 2));
Thread t4 = new Thread(new ThreadRunner(li, tab, 4, 3));
t1.start();
t2.start();
t3.start();
t4.start();
try {
t1.join();
t2.join();
t3.join();
t4.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("time : " + (System.currentTimeMillis() - start) + "ms");
}
}
public class ThreadRunner implements Runnable {
List<Integer> l;
private int inc;
private int start;
private Integer[] tab;
public ThreadRunner(List<Integer> l, Integer[] tab, int inc, int start) {
this.l = l;
this.inc = inc;
this.start = start;
this.tab = tab;
}
@Override
public void run() {
int fake = 0;
for(int i = start; i<l.size(); i+=inc){
fake = l.get(i);
}
System.out.println("fake : " + fake);
}
}
答案 0 :(得分:0)
启动线程然后等待它们完成需要一些时间。我怀疑在列表中迭代几百万个元素所需的时间要长得多。
是什么让您相信这是您的代码中最重要的优化部分,产生线程会加快它的速度?
请记住优化的规则:http://en.wikipedia.org/wiki/Program_optimization#When_to_optimize
注意:您测量执行时间的方式可能会误导您。编写微基准测试非常棘手。
答案 1 :(得分:-2)
Java无法决定它使用哪个核心。您的操作系统将做出决定。所以你的4个线程确实在一个核心上运行。