この質問に触発され、
現在、1万人を超えるユーザーにのみ表示されます
私は次のコードを思いつきました:
$cat loop.c
int main( int argc, char ** argv )
{
int i = 0;
while( i++ < 2147483647 );
}
$cc -o loop loop.c
$ time ./loop
real 0m11.161s
user 0m10.393s
sys 0m0.012s
$cat Loop.java
class Loop {
public static void main( String [] args ) {
int i = 0;
while( i++ < 2147483647 );
}
}
$javac Loop.java
$time java Loop
real 0m4.578s
user 0m3.980s
sys 0m0.048s
JavaバージョンはCバージョンのほぼ3倍の速度で動作するのはなぜですか?ここで何が欠けていますか?
これは、Ubuntu 9.04で実行されます。
インテル(R)Pentium(R)M @ 1.73GHz
32ビット
編集する
これは素晴らしいです。Cで-O3オプションを使用するとループが最適化され、Javaで-serverを使用すると同じことが行われます。これは「最適化された時間」です。
私は期待してjavac
あなたのCコンパイラよりも最適化のいくつかのより高いレベルをデフォルトされます。-O3
ここでコンパイルすると、Cの方がはるかに高速です。
C with -O3
:
real 0m0.003s
user 0m0.000s
sys 0m0.002s
あなたのJavaプログラム:
real 0m0.294s
user 0m0.269s
sys 0m0.051s
もう少し詳細; 最適化なしでは、Cは次のようにコンパイルされます。
0000000100000f18 pushq %rbp
0000000100000f19 movq %rsp,%rbp
0000000100000f1c movl %edi,0xec(%rbp)
0000000100000f1f movq %rsi,0xe0(%rbp)
0000000100000f23 movl $0x00000000,0xfc(%rbp)
0000000100000f2a incl 0xfc(%rbp)
0000000100000f2d movl $0x80000000,%eax
0000000100000f32 cmpl %eax,0xfc(%rbp)
0000000100000f35 jne 0x00000f2a
0000000100000f37 movl $0x00000000,%eax
0000000100000f3c leave
0000000100000f3d ret
最適化(-O3
)を使用すると、次のようになります。
0000000100000f30 pushq %rbp
0000000100000f31 movq %rsp,%rbp
0000000100000f34 xorl %eax,%eax
0000000100000f36 leave
0000000100000f37 ret
ご覧のとおり、ループ全体が削除されています。javap -c Loop
私にJavaバイトコードのこの出力を与えました:
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: iload_1
3: iinc 1, 1
6: ldc #2; //int 2147483647
8: if_icmpge 14
11: goto 2
14: return
}
ループがコンパイルされているようですが、実行時に何かが発生してスピードアップしています。(他の人が述べたように、JITコンパイラーはループを押しつぶします。)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加