我试图找到某种关于反射性能特征的明确答案。除了“除非必须,否则不要使用它”之外,没有什么是真正具体的。也许这没关系,因为用例决定了反射例程运行的好坏。
我会放手,但我已经阅读了几篇文章,这些文章表明 Java 6 使反射例程几乎与任何其他例程一样快,尤其是在您使用 -server 开关的情况下。
我根本没有看到。我在 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 ) ]; }
}