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倍,难道是我姿势不对?