2012-01-02 20 views
0

私はjavaでコンパイルと実行時の計算を理解しようとしています。私は私が方向性と MapLocationsの配列との間に一定のマッピングを定義する、すなわち次 列挙javaコンパイルと実行時の計算

public enum SightSensor{ 

    NORTH (new MapLocation[]{new MapLocation(0,1), 
         new MapLocation(0,2), 
         new MapLocation(0,3)}), 
    SOUTH (new MapLocation[]{new MapLocation(0,-1), 
         new MapLocation(0,-2), 
         new MapLocation(0,-3)}); 

    private final MapLocation[] locs; 

    SightSensor(MapLocation[] locs){ 
    this.locs = locs; 
    } 

    public static MapLocation[] getLocs(Direction dir){ 
    if (dir == Direction.NORTH) 
     return NORTH.locs; 
    if (dir == Direction.SOUTH) 
     return SOUTH.locs; 
    } 
}; 

を持っています。 (おそらくこれは、私は、Javaに新たなんだ?これを行うには間違った方法である。)さて、私はコード内のループ内

MapLocation[] locs = SightSensor.getLocs(Direction.SOUTH_WEST); 

を書く 場合、私はコストがオーバーヘッド最初の時間があることがわかりますコード が呼び出され、実行時に何とか計算/インスタンス化されていることを意味します。私はちょうど直接

MapLocation[] locs = new MapLocation[]{new MapLocation(0,1), 
          new MapLocation(0,2), 
          new MapLocation(0,3)}; 

をコーディングする代わりに 場合は何もコストのオーバーヘッドはありません。私はその違いを理解していない。コンパイラはjust-in-time計算の奇妙な種類の を実行しますか?

+0

コストオーバーヘッドをどのように測定しているか説明できますか? –

+0

また、あなたの例はコンパイルされません。 ( 'dir'がNORTHでもSOUTHでもないとき) –

+0

爪、申し訳ありませんが、コードを簡素化しようとしました。これは' getLocs'に何らかのelse文が必要です。バイトコードでの測定。 – andyInCambridge

答えて

3

あなたが見ているコストは、クラスローディングコストであると思われます。コードが初めてクラスにアクセスすると、クラスローダーはそのバイナリ(.classファイル)をメモリにロードします。これは、ほとんどの実用的な目的のために無視できる1回限りのコストです。また

:今

、私が書く場合...コード内のループ内で、私は

方法、オーバーヘッドコストのコードが呼び出された最初の時間があることを見つけますこの費用を測定しましたか?単一操作の時間コストを測定することはほとんど不可能です。あなたは、ループを通してxMパスを実行するのに必要な時間を測定することができます。次に分けて償却コストを得ることができます。しかし、単一の操作を測定することは困難です。ガベージコレクションサイクル、スレッドに関連したコンテキストスイッチなどを取得している可能性があります。さらに、JIT(Just In Time)コンパイラは、通常、1回の操作でNオペレーションよりも償却コストよりもはるかに高いコストが得られます。

EnumMap<Direction, MapLocation[]> map = new EnumMap(Direction.class); 
map.put(Direction.NORTH, new MapLocation[] { new MapLocation(0, 1), 
               new MapLocation(0, 2), 
               new MapLocation(0, 3) }); 
map.put(Direction.NORTH, new MapLocation[] { new MapLocation(0, -1), 
               new MapLocation(0, -2), 
               new MapLocation(0, -3) }); 

その後、getLocs()呼び出しは単にmap.get(dir)になる:

public static MapLocation[] getLocs(Direction dir) { 
    return valueOf(dir.name()).locs; 
} 

を別の方法としては、型EnumMapの変数でSightSensor列挙型を置き換える使用することができ、次のように

FWIW、私はgetLocs()を記述します

+0

私は実際にバイトコードのコストを測定しているので、タイミングは問題ではありませんが、コンパイルの方法は問題ありません。 – andyInCambridge

+0

バイトコードにはどんな種類の費用がありますか? –

+0

約10000バイトコード – andyInCambridge

2

コンパイラでジャストインタイム計算の奇妙な種類がありますか?

はい、Javaの実行時には、それが実行されるように、コードを最適化するために統計を使用していないん:それについて奇妙な

http://docs.oracle.com/javase/6/docs/technotes/tools/share/jstat.html

何を。

これは、同様に適切であるかもしれない:

個人的に

Real differences between "java -server" and "java -client"?

、私はあなたが最適化を心配できるだけ読んでないようやすいようにコードを書くべきだと思います。スピードアップはおそらく重要ではありません。

+0

返事をありがとう。私はC++から来ているので、私はこれらの詳細をまだ認識していません。 – andyInCambridge

0

これは実際の回答ではありませんが、ヒント:getLocsを非静的にして返すだけです現在の列挙型のlocs

public MapLocation[] getLocs(){ 
    return locs; 
} 

代わりのSightSensor.getLocs(someDir)あなたはその後、someDir.getLocs()を呼び出します。

このようにして、列挙のすべてのメンバーを列挙する必要がなくなります。

関連する問題