- - PR -
static修飾子は多用するべきか
«前のページへ
1|2|3
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2005-12-17 07:37
多分、コンパイラレベルでの最適化ですね。 JDK5.0以前からもJava言語仕様で規定されていますが、 JDK5.0からはStringBufferではなくStringBuilderに置き換えられるみたいですね。 これも聞いた話ですが、最近のSunやIBMのJVMは実行時の最適化に力を入れているらしく、 例えばバイトコード操作ライブラリで、有名なものではJavassistとASMがありますが、 ・ASMは下手な最適化が行われており、実行時の最適化が行われにくい ・JavassistはJava言語仕様どおりにしかコンパイルしない。 そのため、実行時の最適化の恩恵が受けられる との事で、実行速度はJavassistの方が速いらしいです。 Seasar2のAOPも、上記理由からASMをやめてJavassistに変更したと、 作者のブログで読んだ覚えがあります。 | ||||
|
投稿日時: 2005-12-17 16:53
メソッド内でローカルに使うオブジェクトは、 生成・破棄のコストを減らすため、 static変数に置いたインスタンスを使い回すようにできないか …ということを言っていますか? だとしたら、JVMの進化はそういう小手先の技を 必要としないところまで来ています。 http://www-06.ibm.com/jp/developerworks/java/051104/j_j-jtp09275.shtml エスケープ分析といえば、こういう話もありますね。 http://pcweb.mycom.co.jp/news/2005/12/13/020.html この結果、StringBufferの余計な同期化が排除されるようになれば、 StringBuilderとの性能差は無くなってくるのかもしれません。 | ||||
|
投稿日時: 2008-05-28 00:41
[quote]
かつのりさんの書き込み (2005-12-16 18:53) より: [quote] staticフィールドは速いよ。 [/quote] JDK1.1の頃の話でしょうか。 テストしてみましたが、インスタンスのフィールドアクセスと クラスのフィールドアクセスの速度に殆ど差がありません。(JDK5.0) 現在のJVMでは最適化が行われていますし、 小手先の技ではむしろ最適化の邪魔になるケースもあるそうです。 検証コード(汚いですが・・・) [code] public class Test { public static String classField = "classField"; public String instanceField = "instanceField"; public static int cCount = 0; public static int iCount = 0; public static void test(int n) { String variable; Test test = new Test(); variable = Test.classField; long l1,l2,l3; l1 = System.currentTimeMillis(); for(int i = 0; i < 50000000; i++){ variable = Test.classField; } l2 = System.currentTimeMillis(); for(int i = 0; i < 50000000; i++){ variable = test.instanceField; } l3 = System.currentTimeMillis(); System.out.println(n + ":l2 - l1 = " + (l2 - l1)); System.out.println(n + ":l3 - l2 = " + (l3 - l2)); if((l2 - l1) > (l3 - l2)){ cCount++; }else if((l2 - l1) < (l3 - l2)){ iCount++; } } public static void main(String[] args) { for(int i = 0; i < 100; i++){ test(i); } System.out.println("cCount=" + cCount + ":iCount=" + iCount); } } [/code] [/quote] かつのりさんのをall-in-oneで動かしたら、インスタンスの方が断然速かったんですが、以下のように書き換えたら、staticの方がはるかに速かったんですが??? public class Test { public static String classField = "classField"; public String instanceField = "instanceField"; public static int cCount = 0; public static int iCount = 0; public static void stM() { } public void insM() { } public void test(int n) { String variable; // Test test = new Test(); variable = Test.classField; long l1,l2,l3; l1 = System.currentTimeMillis(); for(int i = 0; i < 50000000; i++){ // variable = Test.classField; stM(); } l2 = System.currentTimeMillis(); for(int i = 0; i < 50000000; i++){ // variable = test.instanceField; insM(); } l3 = System.currentTimeMillis(); // System.out.println(n + ":l2 - l1 = " + (l2 - l1)); // System.out.println(n + ":l3 - l2 = " + (l3 - l2)); System.out.println(n + ":sta = " + (l2 - l1)); System.out.println(n + ":ins = " + (l3 - l2)); if((l2 - l1) > (l3 - l2)){ cCount++; }else if((l2 - l1) < (l3 - l2)){ iCount++; } } public static void main(String[] args) { Test test = new Test(); for(int i = 0; i < 100; i++){ test.test(i); } System.out.println("cCount=" + cCount + ":iCount=" + iCount); } } _________________ | ||||
|
投稿日時: 2008-05-28 10:33
かなり古い書き込みに・・・
手元のSunのJRE1.6(32bit)ではあんまり差がないというか、 実行毎によって変わりますね。 どっちにせよ、ランタイムのJITの最適化によってどうにでも変わりますので、 あまりstaticやインスタンスだのを気にする必要はないかと思います。 結局はVMの実装次第です。 全てのケースにおいて高速になるチューニングは難しいので、 より多数派のコードで早くなるようなチューニングを行うことが多いです。 ですので、現時点で速い遅いを気にせずに、 普通にコードを書いた方が得ですよということです。 |
«前のページへ
1|2|3