java与c#都支持反射,但是从网络上搜索两大阵营对于反射的态度,基本上.net开发人员都建议慎用反射,因为会有性能开销;反到是java阵营里好象在大量肆无忌惮的使用反射。于是写了下面的测试代码:
c#版的:
二个project,如上图,Model项目中就只有一个实体类Person,代码如下:
1 using System; 2 3 namespace Model 4 { 5 public class Person 6 { 7 private int Add(object i,object j) 8 { 9 return (int)i + (int)j; 10 } 11 } 12 }
然后在一个Console控制台里反射Model项目生成的dll,并调用Person类的Private方法
1 using System; 2 using System.Diagnostics; 3 using System.Reflection; 4 5 namespace ReflectionStudy 6 { 7 class Program 8 { 9 static void Main(string[] args) 10 { 11 var asm = Assembly.LoadFile(@"R:\Relection\ReflectionStudy\ReflectionStudy\bin\Release\Model.dll"); 12 int i = 0, j = 0, limit = 1000000; 13 Stopwatch watch = new Stopwatch(); 14 watch.Reset(); 15 watch.Start(); 16 for (i = 0; i < limit; i++) 17 { 18 j = TestReflection(asm, i); 19 } 20 watch.Stop(); 21 Console.WriteLine("{0}次反射,平均耗时:{1}毫秒/次", limit, watch.ElapsedMilliseconds / (float)limit); 22 Console.WriteLine(j); 23 Console.Read(); 24 } 25 26 static int TestReflection(Assembly asm, int i) 27 { 28 var person = asm.CreateInstance("Model.Person"); 29 var privateMethod = person.GetType().GetMethod("Add", BindingFlags.Instance | BindingFlags.NonPublic); 30 return (int)privateMethod.Invoke(person, new object[] { i, 1 }); 31 } 32 } 33 }
运行的结果:
1000000次反射,平均耗时:0.003184毫秒/次
1000000
Java版:
如上图,同样二个project,model里就一个类Person,代码跟c#版类似:
1 package jimmy; 2 3 public class Person { 4 private Integer add(Object i,Object j){ 5 return (Integer)i + (Integer)j; 6 } 7 }
RelectionTest里引用model生成的jar包,主要代码如下:
1 package test; 2 3 import java.lang.reflect.Method; 4 import java.text.DecimalFormat; 5 6 public class Program { 7 /** 8 * @param args 9 */ 10 public static void main(String[] args) { 11 try { 12 Class<?> c = Class.forName("jimmy.Person"); 13 Integer i = 0, j = 0, limit = 1000000; 14 long startMili = System.currentTimeMillis(); 15 for (i = 0; i < limit; i++) { 16 j = testReflection(c, i); 17 } 18 long stopMili = System.currentTimeMillis(); 19 20 float elapsedTime = (stopMili - startMili) / (float) limit; 21 DecimalFormat df1=new DecimalFormat("#0.000000"); 22 23 System.out.println(limit +"次反射,平均耗时:" + df1.format(elapsedTime) + "毫秒/次"); 24 System.out.println(j); 25 } catch (Exception e) { 26 e.printStackTrace(); 27 } 28 } 29 30 static Integer testReflection(Class<?> c, Integer i) { 31 try { 32 Method m = c.getMethod("add", Object.class, Object.class); 33 return (Integer) m.invoke(c.newInstance(), i, 1); 34 } catch (Exception e) { 35 e.printStackTrace(); 36 } 37 return 0; 38 39 } 40 41 }
在同一台机器上的运行结果:
1000000次反射,平均耗时:0.000301毫秒/次
1000000
单就这个示例而言,java的反射效率整整高出了c#10倍,难道是我姿势不对?