博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
直接方式,反射方式,dynamic方式性能比较
阅读量:5745 次
发布时间:2019-06-18

本文共 8282 字,大约阅读时间需要 27 分钟。

先上测试代码 

using System.Text;namespace Model{    public partial class Class1    {        public Class1()        { }        private string _s = "";        private int _i = 0;        private decimal _d = 0;        private StringBuilder _sb = new StringBuilder();        public string S        {            set { _s = value; }            get { return _s; }        }        public int I        {            set { _i = value; }            get { return _i; }        }        public decimal D        {            set { _d = value; }            get { return _d; }        }        public StringBuilder SB        {            set { _sb = value; }            get { return _sb; }        }        public int func()        {            int s = 0;            for (int i = 0; i < 1000; i++)            {                s = s + i;            }            return s;        }    }}///using System;using System.Collections.Generic;using System.Linq;using System.Text;using Model;using System.Reflection;using System.Diagnostics;namespace testReflect{    class Program    {        static void Main(string[] args)        {            const int count = 100000;            Console.WriteLine("count="+count);            Stopwatch sw = new Stopwatch();            StringBuilder test = new StringBuilder();            sw.Restart();            for (int i = 0; i < count; i++)            {                Class1 m = new Class1();                m.D = 100;                m.I = 200;                m.S = "string";                m.SB = new StringBuilder("StringBuilder");                test.Append(m.D);                test.Append(m.I);                test.Append(m.S);                test.Append(m.SB);            }            sw.Stop();            Console.WriteLine("直接创建,赋值并访问内存中对象属性:   " + sw.ElapsedTicks);            //Console.WriteLine("直接创建,赋值并访问内存中对象属性:   " + sw.ElapsedTicks);            long basic = sw.ElapsedTicks;            sw.Restart();            test = new StringBuilder();            for (int i = 0; i < count; i++)            {                var t = typeof(Class1);                ConstructorInfo ct = t.GetConstructor(new Type[] { });                var m = ct.Invoke(null);                PropertyInfo pd = t.GetProperty("D");                pd.SetValue(m, 100m, null);                PropertyInfo pi = t.GetProperty("I");                pi.SetValue(m, 200, null);                PropertyInfo ps = t.GetProperty("S");                ps.SetValue(m, "string", null);                PropertyInfo psb = t.GetProperty("StringBuilder");                PropertyInfo[] props = m.GetType().GetProperties();                foreach (var p in props)                {                    test.Append(p.GetValue(m, null));                }            }            sw.Stop();            Console.WriteLine("反射创建,赋值并访问内存中对象属性:   " + sw.ElapsedTicks + "(" + sw.ElapsedTicks / basic + ")");            test = new StringBuilder();            sw.Restart();            for (int i = 0; i < count; i++)            {                dynamic dm = new Class1();                dm.D = 100;                dm.I = 200;                dm.S = "string";                dm.SB = new StringBuilder("StringBuilder");                test.Append(dm.D);                test.Append(dm.I);                test.Append(dm.S);                test.Append(dm.SB);            }            sw.Stop();            Console.WriteLine("dynamic直接创建,赋值并访问内存中对象属性:" + sw.ElapsedTicks + "(" + sw.ElapsedTicks / basic + ")");            test = new StringBuilder();            sw.Restart();            for (int i = 0; i < count; i++)            {                var t = typeof(Class1);                ConstructorInfo ct = t.GetConstructor(new Type[] { });                dynamic dm = ct.Invoke(null);                dm.D = 100;                dm.I = 200;                dm.S = "string";                dm.SB = new StringBuilder("StringBuilder");                test.Append(dm.D);                test.Append(dm.I);                test.Append(dm.S);                test.Append(dm.SB);            }            sw.Stop();            Console.WriteLine("dynamic反射创建,赋值并访问内存中对象属性:" + sw.ElapsedTicks + "(" + sw.ElapsedTicks / basic + ")");            test = new StringBuilder();            sw.Restart();            for (int i = 0; i < count; i++)            {                Class1 m = new Class1();                test.Append(m.func());            }            sw.Stop();            Console.WriteLine("直接调用内存中对象方法:   " + sw.ElapsedTicks + "(" + sw.ElapsedTicks / basic + ")");            sw.Restart();            test = new StringBuilder();            for (int i = 0; i < count; i++)            {                var t = typeof(Class1);                MethodInfo meth = t.GetMethod("func");                ConstructorInfo ct = t.GetConstructor(new Type[] { });                test.Append(meth.Invoke(ct.Invoke(null), null));            }            sw.Stop();            Console.WriteLine("反射调用内存中对象方法:   " + sw.ElapsedTicks + "(" + sw.ElapsedTicks / basic + ")");            test = new StringBuilder();            sw.Restart();            for (int i = 0; i < count; i++)            {                dynamic dm = new Class1();                test.Append(dm.func());            }            sw.Stop();            Console.WriteLine("dynamic直接调用内存中对象方法:" + sw.ElapsedTicks + "(" + sw.ElapsedTicks / basic + ")");            test = new StringBuilder();            sw.Restart();            for (int i = 0; i < count; i++)            {                var t = typeof(Class1);                ConstructorInfo ct = t.GetConstructor(new Type[] { });                dynamic dm = ct.Invoke(null);                test.Append(dm.func());            }            sw.Stop();            Console.WriteLine("dynamic反射调用内存中对象方法:" + sw.ElapsedTicks + "(" + sw.ElapsedTicks / basic + ")");            Console.WriteLine("###############################");            sw.Restart();            test = new StringBuilder();            for (int i = 0; i < count; i++)            {                Assembly a = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + @"\Model.dll");                var t = a.GetType("Model.Class1");                ConstructorInfo ct = t.GetConstructor(new Type[] { });                var rm = ct.Invoke(null);                PropertyInfo pd = t.GetProperty("D");                pd.SetValue(rm, 100m, null);                PropertyInfo pi = t.GetProperty("I");                pi.SetValue(rm, 200, null);                PropertyInfo ps = t.GetProperty("S");                ps.SetValue(rm, "string", null);                PropertyInfo psb = t.GetProperty("SB");                psb.SetValue(rm, new StringBuilder("StringBuilder"), null);                PropertyInfo[] props = t.GetProperties();                foreach (var p in props)                {                    test.Append(p.GetValue(rm, null));                }            }            sw.Stop();            Console.WriteLine("使用反射加载程序集,创建,赋值,访问,对象属性:   " + sw.ElapsedTicks + "(" + sw.ElapsedTicks / basic + ")");            sw.Restart();            test = new StringBuilder();            for (int i = 0; i < count; i++)            {                Assembly a = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + @"\Model.dll");                var t = a.GetType("Model.Class1");                ConstructorInfo ct = t.GetConstructor(new Type[] { });                dynamic dm = ct.Invoke(null);                dm.D = 100m;                dm.I = 200;                dm.S = "string";                dm.SB = new StringBuilder("StringBuilder");                test.Append(dm.D);                test.Append(dm.I);                test.Append(dm.S);                test.Append(dm.SB);            }            sw.Stop();            Console.WriteLine("dynamic赋值,使用反射加载程序集,创建,赋值,访问,对象属性:   " + sw.ElapsedTicks + "(" + sw.ElapsedTicks / basic + ")");        }    }}


分别循环1000,10000,50000,100000次

所得到的数据显示,直接创建赋值是快速的方法。

反射创建所需要的时间比依次是9x,15x,15x,15x

对于两种dynamic,

所需的时间比依次是36,8,3,2和7,4,3,3。说明了在反复调用次数少的情况下,dynamic方式并不优于反射,但是在反复调用次数多的情况下,使用dynamic方式优于直接使用反射。两种dynamic方式在调用次数多的情况下,差距也不是很多

对于方法的调用,发现,时间比都差不多。反射稍慢一点。dynamic方式略占优势。

对于加载assembly的方式,绝对是最慢的,通常要在100-150倍左右。

 


此处我想强调的是,虽然速度差别很大,但是通常的代码运行很少有循环1000次10000次的。即便有,其绝对值还是很小的。相对网络延迟开销,反射所花去的开销可以忽略不计。因此,因为性能问题拒绝反射是愚蠢的。使用dynamic类型,相对反射来说,代码可以写的更优雅。

以上数据,仅供参考。

转载地址:http://hyxzx.baihongyu.com/

你可能感兴趣的文章
underscore.js学习笔记
查看>>
windows下常用命令
查看>>
1.5编程基础之循环控制_29:数字反转
查看>>
组策略 之 设备安装设置
查看>>
人工智能还能干这些?这8种AI应用你可能意想不到
查看>>
实现Hyper-V 虚拟机在不同架构的处理器间迁移
查看>>
简单使用saltstack
查看>>
针对web服务器容灾自动切换方案
查看>>
突破媒体转码效率壁垒 阿里云首推倍速转码
查看>>
容器存储中那些潜在的挑战和机遇
查看>>
R语言的三种聚类方法
查看>>
深入理解Python中的ThreadLocal变量(上)
查看>>
如果一切即服务,为什么需要数据中心?
查看>>
《游戏开发物理学(第2版)》一导读
查看>>
Erlang简史(翻译)
查看>>
深入实践Spring Boot2.4.2 节点和关系实体建模
查看>>
10个巨大的科学难题需要大数据解决方案
查看>>
Setting Up a Kerberos server (with Debian/Ubuntu)
查看>>
用 ThreadLocal 管理用户session
查看>>
setprecision后是要四舍五入吗?
查看>>