Javaのパフォーマンス(一)


プログラムの性能はよく言及される話題であり,比較アルゴリズムでも比較プログラミング言語でもシステムでもプログラムの性能は避けられない話題である.
具体的なプログラム言語を除いて、性能は具体的な実行環境と密接に関連しており、CPU負荷、メモリ使用、IO負荷は性能に影響を与えることができ、これも私たちがプログラム性能をテストするたびに、戻る値が少し異なる原因です.
異なる人の性能に対する理解にも偏差があり、例えば金融取引システムでは、性能の指標は往々にして小さな操作であり、例えば注文処理に数ミリ秒が必要なのか、それとも微妙なのか.より多くのシステムでは、パフォーマンスの指標は、多くの小さな操作を含む大きな操作に数十、数百ミリ秒、さらには数秒数分かかることが多い.1つ目のケースでは、実際には遅延に注目し、後者のケースではスループットに注目します.
Javaプログラマーとして、パフォーマンスはよく取り上げられる問題で、Javaは仮想マシンで実行されていると言われていますが、もちろんC/C++より遅いです.以前Javaシステムを作った例を挙げてJavaがどれだけ遅いかを示す人もいます.ネット上でも多くの言語の性能比較テストがあり、JavaとC/C++の性能が同等であることを示す結果が少なくない.これらの疑問と他の人のテスト結果に直面して、私たちは本当に帰ってJavaプログラムとC++プログラムを書いて実際に比較してみるかもしれませんが、Javaは確かに遅いかもしれませんし、差が少ないかもしれません.
私も似たような疑問や困惑が多く、致命的なボトルネックのある技術を選んだのではないかと心配することがあります.ネットで何回か検索した後、Java仮想マシン自体に焦点を当てた.  
Javaプログラマーは私たちが書いた「.java」の最後のコードファイルを知っているはずです.javacを経て多くの「.class」ファイルにコンパイルされ、その内容はjavaバイトコードと呼ばれています.これらclassファイルはjvmの起動プログラム「java」で実行できます. 
 
//D:/HelloWorld.java
public class HelloWorld {
   public static void main (String []args) {
       int number = Integer.parseInt("100");
       System.out.println("value is " + number);
   }
}

D:\>javac HelloWorld.java
生成されたclass javapでclassファイルを表示できます
D:\>javap -c HelloWorldCompiled from "HelloWorld.java"public class HelloWorld {  public HelloWorld();    Code:       0: aload_0       1: invokespecial #1                 //Method java/lang/Object."":()V       4: return  public static void main(java.lang.String[]);    Code:       0: ldc           #2                 //String 100       2: invokestatic  #3                 //Method java/lang/Integer.parseInt:(Ljava/lang/String;)I       5: istore_1       6: getstatic     #4                 //Field java/lang/System.out:Ljava/io/PrintStream;       9: new           #5                 //class java/lang/StringBuilder      12: dup      13: invokespecial #6                 //Method java/lang/StringBuilder."":()V      16: ldc           #7                 //String value is      18: invokevirtual #8                 //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;      21: iload_1      22: invokevirtual #9                 //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;      25: invokevirtual #10                //Method java/lang/StringBuilder.toString:()Ljava/lang/String;      28: invokevirtual #11                //Method java/io/PrintStream.println:(Ljava/lang/String;)V      31: return}
Javaのパフォーマンスが良いかどうかは、jvmがバイトコードファイルをどのように処理するかによって決まります.同じプログラムでjava 1.5で走るとjava 1より走る可能性があります.8は30%遅い.JAvaの大バージョンの更新のたびに、通常はいくつかのパフォーマンスの最適化があり、新しいバージョンを比較するだけで無料のパフォーマンスの向上を得ることができます.
java 1.3以前、jvmはすべて解釈器の方式でプログラムを実行して、その時のjavaの性能はC/C++より10倍遅いかもしれません.1999年java 1.31 hotspotという仮想マシン実装が含まれており、パフォーマンスが大幅に向上しています.簡単に言えばhotspotは私たちのプログラムの中で非常にhotあるいは何度も呼び出された方法を監視することができて、これらの方法を効率的な原生命令にコンパイルして、再びこれらの方法を実行する時直接原生命令を呼び出すことができます.これは新しいハイブリッド実行モードであり,よく用いられない方法は低効率な解釈で実行され,よく用いられる方法は効率的な原生命令で実行される.JVMは、コンパイル後のメソッドの実行効率を継続的に検出し、異なる最適化メソッドで再コンパイルしてパフォーマンスを向上させます.
なぜコンパイルして実行しないのかという質問がありますが、このような性能はもっと高いのではないでしょうか.もし本当にすべてコンパイルの方式で実行するならば、私达は2つのものを失うことができて、1つは起動速度で、毎回起動する时すべてのclassファイルをコンパイルする必要があるため、2つ目は性能を動的に最適化することができなくて、原生の指令から低レベルで、そのためコンテキストを失って、ほとんど最適化の空間がありません.
jvm実行メカニズムにより,javaの性能がjvmで動的であることが分かった.私たちのプログラムに戻ると、javaプログラムの実際の性能をテストするには、最も多くの呼び出し方法がjvmでコンパイルされ、十分な動的最適化が必要であることがわかります.このプロセスはウォーミングアップ(warmup)と呼ばれています.