Ответ 1
В случае сомнений испытайте! Используя jmh, я получаю следующие результаты в списке из 100 тыс. Элементов (в микросекундах, меньше - лучше):
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
Итак, у вас есть от более быстрого до более медленного:
-
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. Если логика в сопоставлении более сложна, некоторые из оптимизаций могут быть недоступны (более длинный код = меньше вложения), и в этом случае версии потоков могут занимать 4-5 раз больше времени, чем цикл for, но если эта логика является тяжелой 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();
}
}