Joh*_*iva 10 java performance java-8 java-stream
我试图计算列表中值的平方和.以下是三种变体,它们都计算出所需的值.我想知道哪一个最有效率.我期待第三个更高效,因为自动拳击只进行一次.
// sum of squares
int sum = list.stream().map(x -> x * x).reduce((x, y) -> x + y).get();
System.out.println("sum of squares: " + sum);
sum = list.stream().mapToInt(x -> x * x).sum();
System.out.println("sum of squares: " + sum);
sum = list.stream().mapToInt(x -> x).map(x -> x * x).sum();
System.out.println("sum of squares: " + sum);
Run Code Online (Sandbox Code Playgroud)
ass*_*ias 10
如有疑问,请测试!使用jmh,我在100k元素列表中得到以下结果(以微秒为单位,越小越好):
Benchmark Mode Samples Score Error Units
c.a.p.SO32462798.for_loop avgt 10 119.110 0.921 us/op
c.a.p.SO32462798.mapToInt avgt 10 129.702 1.040 us/op
c.a.p.SO32462798.mapToInt_map avgt 10 129.753 1.516 us/op
c.a.p.SO32462798.map_reduce avgt 10 1262.802 12.197 us/op
c.a.p.SO32462798.summingInt avgt 10 134.821 1.203 us/op
Run Code Online (Sandbox Code Playgroud)
所以你有,从快到慢:
for(int i : list) sum += i*i;
mapToInt(x -> x * x).sum()
和 mapToInt(x -> x).map(x -> x * x).sum()
collect(Collectors.summingInt(x -> x * x))
map(x -> x * x).reduce((x, y) -> x + y).get()
请注意,结果很大程度上取决于JIT优化.如果映射中的逻辑更复杂,则某些优化可能不可用(更长的代码=更少的内联),在这种情况下,流版本可能需要比for循环多4-5倍的时间 - 但如果该逻辑是CPU重的话差异将再次减少.分析您的实际应用程序将为您提供更多信息.
基准代码供参考:
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
public class SO32462798 {
List<Integer> list;
@Setup public void setup() {
list = new Random().ints(100_000).boxed().collect(toList());
}
@Benchmark public int for_loop() {
int sum = 0;
for (int i : list) sum += i * i;
return sum;
}
@Benchmark public int summingInt() {
return list.stream().collect(Collectors.summingInt(x -> x * x));
}
@Benchmark public int mapToInt() {
return list.stream().mapToInt(x -> x * x).sum();
}
@Benchmark public int mapToInt_map() {
return list.stream().mapToInt(x -> x).map(x -> x * x).sum();
}
@Benchmark public int map_reduce() {
return list.stream().map(x -> x * x).reduce((x, y) -> x + y).get();
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1621 次 |
最近记录: |