美文网首页
c#中几种创建对象的方式的对比

c#中几种创建对象的方式的对比

作者: 有点胖的小乐乐 | 来源:发表于2017-10-18 21:38 被阅读872次

最近学习了msil,发现了很多好玩的,今天介绍一个用IL来创建对象的方式

1.最常见的两种创建对象方式

public static T Create<T>() where T : new()
        {
            return new T();
        }

        public static object CreateNative()
        {
            return new object();
        }

写一个测试帮助方法简单的测试下这两个方法的执行时间的长短:

   public static void Measure(string what, int reps, Action action)
   {
            action();  //warm up

            double[] results = new double[reps];
            for (int i = 0; i < reps; i++)
            {
                Stopwatch sw = Stopwatch.StartNew();
                action();
                results[i] = sw.Elapsed.TotalMilliseconds;
            }
            Console.WriteLine("{0} - AVG = {1}, MIN = {2}, MAX = {3}", what,
                results.Average(), results.Min(), results.Max());
  }

调用测试方法:

            int reps = 5;
            int its = 100000;

            Measure("create", reps, () =>
             {
                 for (int i = 0; i < its; i++)
                 {
                     Create<object>();
                 }
             });

            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            Measure("createNative", reps, () =>
            {
                for (int i = 0; i < its; i++)
                {
                    CreateNative();
                }
            });

执行结果:

测试结果

可以通过测试结果看出来本地方法创建的比泛型方式创建的消耗的时间短,这是为什么。用工具查看生成的il就可以发现为什么了。
泛型方式生成的IL如下:


泛型方式生成的IL

本地方式的生成IL如下:


本地方式生成的IL
可以看出泛型方式生成的IL里面调用了Activator.CreateInstance方法,而本地方式而直接new一个对象。所以本地方式的生成对象要比泛型方式用时短。既然这样直接通过Activator.CreateInstance 生成对象呢。

2.Activator.CreateInstance方式生成对象

       public static object CreateReflect(Type type)
        {
            return Activator.CreateInstance(type);
        }  

现在再来比较这三种的生成方式的用时长短,用同样的方式调用CreateReflect,得到结果如下:


三种方式

从结果上看可以看出最快的是本地直接new,第二快是通过Activator.CreateInstance,最慢的则是泛型实例化创建对象。
在工作中泛型创建对象很常见。如何解决泛型创建对象慢的问题呢?

3.使用IL来创建泛型对象

public class CreationHelper<T> where T : new()
    {
        public static Func<T> objCreator = null;

        public static T New()
        {
            if (objCreator == null)
            {
                Type objectType = typeof(T);

                ConstructorInfo defaultCtor = objectType.GetConstructor(new Type[] { });

                DynamicMethod dynMethod = new DynamicMethod(
                    name: string.Format("_{0:N}", Guid.NewGuid()),
                    returnType: objectType,
                    parameterTypes: null);

                var gen = dynMethod.GetILGenerator();
                gen.Emit(OpCodes.Newobj, defaultCtor);
                gen.Emit(OpCodes.Ret);

                objCreator = dynMethod.CreateDelegate(typeof(Func<T>)) as Func<T>;
            }

            return objCreator();
        }
 }

用以上相同的方式来测试,测试代码:

           GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            Measure("DynamicCreate", reps, () =>
            {
                for (int i = 0; i < its; i++)
                {
                    CreationHelper<object>.New();
                }
            });

测试结果如下:


四种测试

结果一目了然,IL方式创建对象的用时在本地实例化和Activator.CreateInstance之间,只比本地实例化稍慢。所以泛型实例化可以考虑这种方式,可以提升泛型实例化的效率。

4.总结

本文介绍了c#创建对象的4种方式,简单的比较了这四种创建效率。说明了IL的效率果然是高。学会了高效的创建泛型对象的一种方式。

相关文章

  • c#中几种创建对象的方式的对比

    最近学习了msil,发现了很多好玩的,今天介绍一个用IL来创建对象的方式 1.最常见的两种创建对象方式 写一个测试...

  • Javascript中创建对象的几种方式

    一、一般来说,最简单的创建方式就是字面量方式 或是创建一个Object实例,再给他添加属性和方法 缺点:很明显,当...

  • js中创建对象的几种方式

    博客原文地址:Claiyre的个人博客 https://claiyre.github.io/博客园地址:http:...

  • JavaScript中创建对象的几种方式

    在《JavaScript高级程序设计》中,介绍了创建对象的7种方式,分别是:工厂模式、构造函数模式、原型模式、构造...

  • javascript面向对象与原型

    昨天我们讲了在面向对象中创建对象的几种方式 工厂模式 构造函数模式 工厂模式创建的对象,像工厂一样来创建对象,创建...

  • 创建对象的几种方式

    字面量方式和Object构造函数方式创建对象 优点: 方便缺点: 当需要创建很对对象的时候,会有很多重复的代码 工...

  • 创建对象的几种方式

    第一种:对象字面量的方式 第二种:创建Object实例: 第三种:数构造函数无参数构造函数 带参数的构造函数 第四...

  • 创建对象的几种方式

    真是百看不如一练啊 /*var box= new Object(); //创建一个对象 box.name= "xi...

  • 创建对象的几种方式

    字面量创建对象 new Object() 创建对象 工厂模式 构造函数 原型 混合

  • 创建对象的几种方式

    字面量式(最常用) 调用系统的Object构造函数,创建实例对象 工厂模式 构造函数模式 与工厂模式的区别: 没有...

网友评论

      本文标题:c#中几种创建对象的方式的对比

      本文链接:https://www.haomeiwen.com/subject/vktyuxtx.html