我试图找出总结整数列表的最快方法。
首先,我创建了一个提供采样数据的方法:
public static List<Integer> getIntList(int size) {
LinkedList<Integer> sampleList = new LinkedList<>();
Random rand = new Random();
rand.ints(size).forEach((num)-> sampleList.add(num));
return sampleList;
}
然后我尝试了一些不同的方法来总结List。 首先是最糟糕的一个:
public static void sumUpWithForLoop(List<Integer> data) {
System.out.println("For-loop:");
long start = System.currentTimeMillis();
int listLenght = data.size();
int total = 0;
for (int i = 0; i < listLenght; i++) {
total += data.get(i);
}
long end = System.currentTimeMillis();
System.out.println("Result: " + total);
System.out.println("Duration: " + (end - start) + "ms");
}
在运行这个类之后我注意到它很慢,因为它总是使用get(index)
这需要很长时间。
因此我尝试用Iterator总结List
public static void sumUpWithItterator(List<Integer> data) {
System.out.println("Iterator:");
long start = System.currentTimeMillis();
int total = 0;
for (Integer num : data) {
total += num;
}
long end = System.currentTimeMillis();
System.out.println("Result: " + total);
System.out.println("Duration: " + (end - start) + "ms");
}
这种方法是迄今为止总结一个Integer-List的最快方法,但我仍然试图找到一个更快的方法。
我还尝试使用.stream()
和.parallelStream()
:
public static void sumUpWithNormalStream(List<Integer> data) {
System.out.println("Stream");
long start = System.currentTimeMillis();
int total = data.stream().mapToInt(num -> num).sum();
long end = System.currentTimeMillis();
System.out.println("Result: " + total);
System.out.println("Duration: " + (end - start) + "ms");
}
public static void sumUpWithParallelStream(List<Integer> data) {
System.out.println("ParallelStream");
long start = System.currentTimeMillis();
int total = data.parallelStream().mapToInt(num->num).sum();
long end = System.currentTimeMillis();
System.out.println("Result: " + total);
System.out.println("Duration: " + (end - start) + "ms");
}
正常stream
几乎与迭代器一样快,而parallelStream
比迭代器慢得多。我猜这是由于并行化的开销以及总结List是一个运行得非常快并且不必等待数据库操作等事情的事实。
总而言之,我对目前的方法仍然不满意,但我还没有找到更快的方法。 你有什么想法比普通的迭代器更快地总结一个List。
感谢您的支持。
答案 0 :(得分:2)
使用ArrayList<Integer>
代替LinkedList<integer>
可能会为您带来更好的效果。而且,当这些元素在RAM上彼此相邻存储时,逐个访问元素最快,请尝试使用int[]
。
通常,如果要提高任何程序的性能,请尝试使用迭代和低级代码替换任何函数调用或高级代码。这应该会显着提高性能。
答案 1 :(得分:2)
在你的例子中,内存访问可能是瓶颈,因为添加整数是非常快的操作,但是访问链表的下一个元素需要两次内存访问(一个用于获取下一个节点,另一个用于访问整数值 - 类型擦除使得不可能使用未装箱的价值)。还要记住,链表可能分散在内存中,因此高速缓存未命中的概率很高。
因此,为了加快速度,您应该减少内存访问开销。从LinkedList更改为ArrayList将删除单个访问(到内存中的随机位置)。从ArrayList更改为原始数组将删除第二个,因为在这种情况下,未装箱的整数将存储在内存中。
因此基于int[]
的版本应该是最快的(但不如ArrayList<Integer>
版本灵活)。