C#中使用反射的使用实现和性能分析
作者:kingwign009 | 来源:互联网 | 2017-08-15 01:27
C#中使用反射的使用实现和性能分析--Linux通用技术-Linux编程与内核信息,下面是详情阅读。
最近在研究一个可配置系统的框架,在代码中大量使用了反射的方法,虽然借鉴到其他的语言,如Java中反射性能都比较差,但是想到C#既然是一种强类型的语言,对于AppDomain中的类的调用应该性能不会差很多。
今天在mvp站点上看到有人说反射的性能很差,要避免使用,就写了一个简单的例子测试了一下
测试类如下:
namespace ReflectionTest.Test
{
public class CTester
{
public CTester()
{
a = 10;
}
public void test1()
{
a = (a - 0.0001) * 1.0001;
}
private double a;
public double geta() { return a; }
}
}
首先我们对于对象的构造进行测试
测试代码如下
private void test1()
{
label1.Text = "";
label3.Text = "";
DateTime now = DateTime.Now;
for (int i = 0; i <1000; i++)
{
for (int j = 0; j <100; j++)
{
CTester aTest = new CTester();
}
}
TimeSpan spand = DateTime.Now - now;
label1.Text = "time past " + spand.ToString();
}
private void test2()
{
label2.Text = "";
label4.Text = "";
DateTime now = DateTime.Now;
for (int i = 0; i <1000; i++)
{
for (int j = 0; j <100; j++)
{
Type theTest = Type.GetType("ReflectionTest.Test.CTester");
object theobj = theTest.InvokeMember(null, BindingFlags.CreateInstance
, null, null, null);
}
}
TimeSpan spand = DateTime.Now - now;
label2.Text = "time past " + spand.ToString();
}
测试结果直接调用的时间为16ms左右,而反射调用的则始终维持在5s 520ms左右,直接效率比较接近350倍。
对于这个测试,很有趣的一点是:
如果将test2中的Type theTest = Type.GetType("ReflectionTest.Test.CTester");
移到循环之外,则相应的运行时间下降为1s 332 ms , 效率相差为20倍左右。
接下来我们对成员函数调用进行了测试:
test1:
private void button1_Click(object sender, EventArgs e)
{
DateTime now = DateTime.Now;
CTester aTest = new CTester();
for (int i = 0; i <1000; i++)
{
for (int j = 0; j <100; j++)
{
aTest.test1();
}
}
TimeSpan spand = DateTime.Now - now;
label1.Text = "time past " + spand.ToString();
label3.Text = "value is now " + aTest.geta();
}
test2:
private void button2_Click(object sender, EventArgs e)
{
DateTime now = DateTime.Now;
Type theTest = Type.GetType("ReflectionTest.Test.CTester");
object theobj = theTest.InvokeMember(null, BindingFlags.CreateInstance
, null, null, null);
for (int i = 0; i <1000; i++)
{
for (int j = 0; j <100; j++)
{
theTest.InvokeMember("test1", BindingFlags.InvokeMethod, null, theobj, new object[0]);
}
}
CTester thewar = theobj as CTester;
TimeSpan spand = DateTime.Now - now;
label2.Text = "time past " + spand.ToString();
label4.Text = "value is now " + thewar.geta();
}
这个例子仅仅使用了invoke member进行测试
初步得到的数据如下:
test1 : 10 ms
test2: 2m 53ms
多次测试,得到的数据有轻微的波动,但是基本上的比例维持在1:250左右
对于静态方法调用
结果为5ms - 3m 164ms
用ILDASM查看声称的IL代码,发现除了函数调用外,声称的代码基本一致,可见性能的差别是由
callvirt instance object [mscorlib]System.Type::InvokeMember(string,
valuetype [mscorlib]System.Reflection.BindingFlags,
class [mscorlib]System.Reflection.Binder,
object,
object[])
导致的,也就是反射引起的性能损失。
虽然只用invokemember尝试了一些简单的反射,但是很显然的,反射得消耗是非常大的。
推荐阅读
本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ...
[详细]
蜡笔小新 2023-12-14 14:15:30
本文介绍了在Python中调用同一个类中的方法需要加上self参数,并且规范写法要求每个函数的第一个参数都为self。同时还介绍了如何调用另一个类中的方法。详细内容请阅读剩余部分。 ...
[详细]
蜡笔小新 2023-12-14 12:52:55
本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ...
[详细]
蜡笔小新 2023-12-13 15:02:30
本文介绍了使用switch语句时的一些用法和注意事项,包括如何实现"fall through"、default语句的作用、在case语句中定义变量时可能出现的问题以及解决方法。同时也提到了C#严格控制switch分支不允许贯穿的规定。通过本文的介绍,读者可以更好地理解和使用switch语句。 ...
[详细]
蜡笔小新 2023-12-13 14:47:39
闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ...
[详细]
蜡笔小新 2023-12-13 10:46:54
本文介绍了在ASP.NET 2.0中使用FormView控件来实现自定义的显示外观,与GridView和DetailsView不同,FormView使用模板来呈现,可以实现不规则的外观呈现。同时还介绍了TemplateField的用法和FormView与DetailsView的区别。 ...
[详细]
蜡笔小新 2023-12-13 08:07:00
本文介绍了在C# WPF中实现自定义按钮的方法,包括使用图片作为按钮背景、自定义鼠标进入效果、自定义按压效果和自定义禁用效果。通过创建CustomButton.cs类和ButtonStyles.xaml资源文件,设计按钮的Style并添加所需的依赖属性,可以实现自定义按钮的效果。示例代码在ButtonStyles.xaml中给出。 ...
[详细]
蜡笔小新 2023-12-13 04:22:57
摘要: 在测试数据中,生成中文姓名是一个常见的需求。本文介绍了使用C#编写的随机生成中文姓名的方法,并分享了相关代码。作者欢迎读者提出意见和建议。 ...
[详细]
蜡笔小新 2023-12-12 20:40:34
本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ...
[详细]
蜡笔小新 2023-12-12 19:29:55
导出功能protectedvoidbtnExport(objectsender,EventArgse){用来打开下载窗口stringfileName中 ...
[详细]
蜡笔小新 2023-12-12 14:34:29
本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ...
[详细]
蜡笔小新 2023-12-12 12:55:55
本文是关于C#类型系统、值类型和引用类型的概念性笔记。介绍了C#1系统类型的三个特性,静态类型的含义,显式类型和隐式类型的区别。还讨论了类、结构、数组类型、枚举、委托类型和接口类型属于哪一种类型。同时纠正了关于结构、引用类型和对象传递的错误表述。最后提到了C#4中使用动态类型的关键字。 ...
[详细]
蜡笔小新 2023-12-11 13:15:28
本文介绍了如何在HTML5网页模板中加入百度统计,并对模板文件、css样式表、js插件库等内容进行了说明。同时还解答了关于HTML5网页模板的使用方法、表单提交、域名和空间的问题,并介绍了如何使用Visual Studio 2010创建HTML5模板。此外,还提到了使用Jquery编写美好的HTML5前端框架模板的方法,以及制作企业HTML5网站模板和支持HTML5的CMS。 ...
[详细]
蜡笔小新 2023-12-11 12:06:41
本文介绍了JavaScript的起源和发展历程,以及其在前端验证和服务器端开发中的应用。同时,还介绍了ECMAScript标准、DOM对象和BOM对象的作用及特点。最后,对JavaScript作为解释型语言和编译型语言的区别进行了说明。 ...
[详细]
蜡笔小新 2023-12-10 17:45:49
本文整理了315道Python基础题目及答案,帮助读者检验学习成果。文章介绍了学习Python的途径、Python与其他编程语言的对比、解释型和编译型编程语言的简述、Python解释器的种类和特点、位和字节的关系、以及至少5个PEP8规范。对于想要检验自己学习成果的读者,这些题目将是一个不错的选择。请注意,答案在视频中,本文不提供答案。 ...
[详细]
蜡笔小新 2023-12-10 14:33:46
kingwign009
这个家伙很懒,什么也没留下!