私は、反射の性能特性に関するある種の決定的な答えを見つけようとしました。「必要がない限り使用しないでください」以外には、具体的なものは何もありません。ユースケースによって、リフレクションルーチンの実行の良し悪しが決まるため、おそらくそれで問題ありません。
私はそれを手放したいと思いますが、特に -server スイッチを使用する場合、Java 6 が他のルーチンとほぼ同じくらい高速にリフレクション ルーチンを作成することを示唆するいくつかの記事を読みました。
私はそれをまったく見ていません。Mac 10.8.4 で Java 6 を使用しています。
私のルーチンを見てください。私はランダムなものだけを使用するので、コンパイラ/ランタイムが何らかの方法でリテラルを最適化しないことを願っています。for ループを長時間実行したままにしましたが、直接ルーチンでは約 13 ~ 15 ミリ秒、リフレクティブ ルーチンでは約 590 ~ 595 ミリ秒の値が常に得られます。
import java.lang.reflect.Field;
import java.util.Random;
public class Reflection {
static final int ITERATIONS = 100000;
static final String[] STRINGS = { "asdf", "qwer", "dfgh", "scvb", "ertyerty" };
static final Random random = new Random( System.currentTimeMillis() );
public static void main( String[] args ) throws Exception {
for ( int i = 0; true; i++ ) {
System.out.println( "i=" + i + ", direct=" + testDirectCallSpeed() + ", reflective=" + testReflectiveCallSpeed() );
}
}
static class Blah {
String a, b, c, d, e, f;
int g, h, i, j, k, l;
public String toString() {
StringBuilder sb = new StringBuilder( 100 );
sb.append( super.toString() );
sb.append( ", a=" ).append( a );
sb.append( ", b=" ).append( b );
sb.append( ", c=" ).append( c );
sb.append( ", d=" ).append( d );
sb.append( ", e=" ).append( e );
sb.append( ", f=" ).append( f );
sb.append( ", g=" ).append( g );
sb.append( ", h=" ).append( h );
sb.append( ", i=" ).append( i );
sb.append( ", j=" ).append( j );
sb.append( ", k=" ).append( k );
sb.append( ", l=" ).append( l );
return sb.toString();
}
}
public static long testDirectCallSpeed() {
System.gc();
Blah[] blahs = new Blah[ ITERATIONS ];
long begin = System.currentTimeMillis();
Blah blah;
for ( int i = 0; i < ITERATIONS; i++ ) {
blah = new Blah();
blah.a = getString();
blah.b = getString();
blah.c = getString();
blah.d = getString();
blah.e = getString();
blah.f = getString();
blah.g = getInt();
blah.h = getInt();
blah.i = getInt();
blah.j = getInt();
blah.k = getInt();
blah.l = getInt();
blahs[ i ] = blah;
}
printRandomBlah( blahs );
return System.currentTimeMillis() - begin;
}
public static long testReflectiveCallSpeed() throws Exception {
System.gc();
Blah[] blahs = new Blah[ ITERATIONS ];
long begin = System.currentTimeMillis();
Blah blah;
Class<?> type;
for ( int i = 0; i < ITERATIONS; i++ ) {
blah = new Blah();
for ( Field f : Blah.class.getDeclaredFields() ) {
type = f.getType();
if ( String.class == type ) f.set( blah, getString() );
else if ( int.class == type ) f.setInt( blah, getInt() );
}
blahs[ i ] = blah;
}
printRandomBlah( blahs );
return System.currentTimeMillis() - begin;
}
public static void printRandomBlah( Blah[] blahs ) {
// System.out.println( blahs[ random.nextInt( blahs.length ) ] );
}
public static int getInt() { return random.nextInt(); }
public static String getString() { return STRINGS[ random.nextInt( STRINGS.length ) ]; }
}