2014/09/07追伸
この記事は適切な記事ではありません。
詳細は、「Java 8 Lambda 性能測定の再検証」を参照してください。
はじめに
巷ではJava 8のStream APIの性能測定で盛り上がっています。
でも、Stream APIの性能云々の前に、Lambdaの使用有無で性能がどのように異なるかを検証します。
性能測定
1~1,000,000の総和($\sum_{i=1}^n i$)を求めます(総和がオーバーフローしますが)。
- 単純なfor文で総和を計算
- 1をLambda経由で呼び出す
プログラム
Lambda1.java
public class Lambda1 {
private static final int SIZE = 1_000_000;
void process() {
final IntConsumer c = i -> sum();
//warming up
for(int i=10000; i>0; i--){
c.accept(0);
sum();
}
//Call via lambda
long start = System.nanoTime();
for(int i=100; i>0; i--){
c.accept(0);
}
long end = System.nanoTime();
printResult("000", end - start);
//Call directly
start = System.nanoTime();
for(int i=100; i>0; i--){
sum();
}
end = System.nanoTime();
printResult("001", end - start);
}
private int sum() {
int sum = 0;
for (int i = 0; i <= SIZE; i++) {
sum += i;
}
return sum;
}
private void printResult(String prefix, long time) {
System.err.println(prefix + ": elapsed=" + time / 1_000);
}
public static void main(String[] args) {
new Lambda1().process();
}
}
測定環境
Key | Value |
---|---|
CPU | Intel Core i7-2670QM CPU @ 2.20GHz コア数4 スレッド数8 |
RAM | 8GB |
OS | Windows 7 Home Premium SP1 64ビット版 |
Java | Java SE 8 Update 20 |
ウォーミングアップありの測定結果
000: elapsed=9
001: elapsed=93259
ウォーミングアップなしの測定結果
上のプログラムで、次のようにコメントを付けて、再度実行します。
//warming up
// for(int i=10000; i>0; i--){
// c.accept(0);
// sum();
// }
結果は次のようになりました。
000: elapsed=149481
001: elapsed=113041
まとめ
Lambdaをウォーミングアップすると、直接メソッドを呼び出すよりも、非常(異常)に高速になるようです。