##実験してみました
比較対象は主にstreamの操作です.
以下では数値リストの足し算に
mapToInt(v -> v).sum()
を使うか
collect(Collectors.summingInt(Integer::intValue)))
を使うか
加えて、
中間操作と終端操作の処理内容を別関数に分けるか
すべて一つの関数でまとめるか
について比較しています.
ProcessingTest.java
package mk42;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
public class ProcessingTest {
public static void main(String[] args) {
long startTime = System.nanoTime();
run(generate.get());
long endTime = System.nanoTime();
Mk42.echo.accept("Processing Time : " + (endTime - startTime) + " ns");
}
/**
* Processing speed test.
*
* @param list
*/
private static void run(List<String> list) {
try {
// fastest
Mk42.echo.accept(list.stream().filter(Objects::nonNull).map(add3.andThen(convertInt)).mapToInt(v -> v).sum());
// normal
Mk42.echo.accept(list.stream().filter(Objects::nonNull).map(add3.andThen(convertInt))
.collect(Collectors.summingInt(Integer::intValue)));
// bad
all.accept(list);
} catch (NumberFormatException e) {
Mk42.echo.accept(join.apply(list));
}
}
/** A series of processing */
static Consumer<List<String>> all = v -> {
Mk42.echo.accept(
v.stream().filter(Objects::nonNull).map(x -> x + "3").map(Integer::parseInt).mapToInt(z -> z).sum());
};
/** Add 3 */
static UnaryOperator<String> add3 = v -> v + "3";
/** Convert to Integer */
static Function<Object, Integer> convertInt = v -> Integer.parseInt(String.valueOf(v));
/** Join with comma */
static Function<List<String>, String> join = v -> v.stream().collect(Collectors.joining(","));
/** Generate List which can convert to Integer */
static Supplier<List<String>> generate = () -> Arrays.asList(null, "1", "2", "3", "4", "5");
}
ちなみにMk42とは
Mk42.java
package mk42;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* Answer to the Ultimate Question of Life, the Universe, and Everything.
*/
public class Mk42 {
/** echo */
public static Consumer<Object> echo = v -> System.out.println(v);
/** not null */
public static Predicate<Object> notNull = v -> Optional.ofNullable(v).isPresent();
/** sum list */
public static Function<List<Integer>, Integer> sum = v -> v.stream().filter(notNull).mapToInt(i -> i).sum();
/** generate String list */
public static Supplier<List<String>> strList = () -> Arrays.asList(null, "", " ", "a", "0");
/** generate Integer list */
public static Supplier<List<Integer>> intList = () -> Arrays.asList(null, 1, 2, 3, 4, 5);
}
##結果
- 操作分割 終端操作mapToIntからのsum
処理時間:2261200 ns - 操作分割 終端操作collect
処理時間:3573700 ns - 操作結合 終端操作mapToInt
処理時間:16587300 ns
##で?
操作の関数を分けたほうが早いみたいです.
今回のメインは終端操作なんですが
mapToIntよりcollectでのCollectors呼び出しのほうが遅いですね
オブジェクト呼び出してるから当たり前っぽいですね
細やかなことかもですが、似ている処理ならどちらのほうが処理速度が速いか
覚えていきたいものです