下記のサイトに触発されてなぜ、javaの方が速いのか
検証してみました。
http://pastebin.com/vakRknDk
【ケース1】javaでも遅いケース
class B extends bench { int get() { return 1;} }
class C extends bench { int get() { return 2;} }
abstract public class bench {
abstract int get();
public static void main(String args[]) {
bench f = new B();
bench f2 = new C();
int sum=0;
sum = bench.test(f, f2);
System.out.println(sum);
}
static int test(bench f1, bench f2) {
int sum=0;
bench f=f1;
for( int i=0; i<1000000000; i++ )
{
if(i%2==0)
{
f = f1;
}
else
{
f = f2;
}
sum+=f.get();
}
return sum;
}
}
【ケース2】javaが速くなるケース
class B extends bench2 { int get() { return 1;} }
class C extends bench2 { int get() { return 2;} }
abstract public class bench2 {
abstract int get();
public static void main(String args[]) {
bench2 f = new B();
bench2 f2 = new C();
int sum=0;
sum = bench2.test(f, f2);
System.out.println(sum);
}
static int test(bench2 f1, bench2 f2) {
int sum=0;
bench2 f=f1;
for( int i=0; i<1000000000; i++ )
{
if(i%2==0)
{
f = f1;
sum+=f.get();
}
else
{
f = f2;
sum+=f.get();
}
}
return sum;
}
}
【ケース3】Cのケース
#include <stdio.h>
struct bench {
virtual int get() const = 0;
static int test(bench *f1, bench *f2) {
int sum=0;
bench *f;
for( long i=0; i<1000000000; i++ )
{
if(i%2==0)
{
f = f1;
}
else
{
f = f2;
}
sum+=f->get();
}
return sum;
}
};
class B : public bench { int get() const { return 1; } };
class C : public bench { int get() const { return 2; } };
int main() {
bench *f = new B();
bench *f2 = new C();
int sum=0;
sum = bench::test(f, f2);
printf("%d\n", sum);
return 0;
}
ケース1:4s
ケース2:2.4s
ケース3(最適化なし):6.5s
ケース3(-O1):3.4s
ケース3(-O2):2.7s
ケース1とケース2の違いは
f.getのコンパイル結果をインラインにするために
ケース2ではifブロックの中で一意に呼び出しを行うようにしてみました。
ケース1では分岐の後のf.getはBクラスのgetだったり、Cクラスのgetだったりするため、呼び出しロジックに動的コンパイルされるようにしています。
ケース3のC++の場合は静的コンパイルしか対応できないため
ケース1と同様のロジック呼び出しにしかなりません。
個人的にはケース1の方が綺麗だと思いますが。。
わかりやすいベンチマークをありがとう♪
[0回]
PR