java与c#的反射性能比较

时间:2022-04-23
本文章向大家介绍java与c#的反射性能比较,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

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