C# dynamic 适用场景进一步说明

从代码写的角度上说,有一定的方便性,但还需要从性能的角度做为主要参考因素

下面贴下性能相磁的测评:

  class Test :ITest{
            public int Calculate(int i)=>i++;
            //static public Test Create()=>new Test();
        }
        interface ITest {
            int Calculate(int i);
        }
        [TestMethod]
        public void m22() {
            var dy_checker = new Stopwatch();
            var obj_checker = new Stopwatch();
            var time = 100 * 100000;
            var x2 = typeof(Test);
            ITest w = (ITest)Activator.CreateInstance(x2);
            obj_checker.Start();
            for (int i = 0; i < time; i++) {
                //x2.GetMethod("Calculate").Invoke(w, new object[] { 1 });
                w.Calculate(1);
            }
            obj_checker.Stop();
            dy_checker.Start();
            for (int i = 0; i < time; i++) {
                dynamic x3 = w;
                x3.Calculate(1);
            }
            dy_checker.Stop();
            Console.WriteLine("dy:{0}", dy_checker.ElapsedMilliseconds);
            Console.WriteLine("obj:{0}", obj_checker.ElapsedMilliseconds);
        }
        [TestMethod]
        public void m21() {
            var dy_checker = new Stopwatch();
            var obj_checker = new Stopwatch();
            var time = 100 * 100000;
            var x2 = typeof(Test);
            Test w = (Test)Activator.CreateInstance(x2);
            obj_checker.Start();
            for (int i = 0; i < time; i++) {
                x2.GetMethod("Calculate").Invoke(w,new object[]{1 });
            }
            obj_checker.Stop();
            dy_checker.Start();
            for (int i = 0; i < time; i++) {
                dynamic x3 = w;
                x3.Calculate(1);
            }
            dy_checker.Stop();
            Console.WriteLine("dy:{0}", dy_checker.ElapsedMilliseconds);
            Console.WriteLine("obj:{0}", obj_checker.ElapsedMilliseconds);
        }
        [TestMethod]
        public void m20() {
            var dy_checker = new Stopwatch();
            var obj_checker = new Stopwatch();
            var time = 100 * 100000;
            obj_checker.Start();
            for (int i = 0; i < time; i++) {
                object x2 = new Test();
                ((Test)x2).Calculate(1);
            }
            obj_checker.Stop();
            dy_checker.Start();
            for (int i = 0; i < time; i++) {
                dynamic x3 = new Test();
                x3.Calculate(1);
            }
            dy_checker.Stop();
            Console.WriteLine("dy:{0}", dy_checker.ElapsedMilliseconds);
            Console.WriteLine("obj:{0}", obj_checker.ElapsedMilliseconds);
        }
        [TestMethod]
        public void m19() {
            var dy_checker = new Stopwatch();
            var obj_checker = new Stopwatch();
            var var_checker = new Stopwatch();
            var time = 100 * 100000;
            var_checker.Start();
            for (int i = 0; i < time; i++) {
                var x3 = 3;
                var x33 = x3 + 5;
            }
            var_checker.Stop();

            obj_checker.Start();
            for (int i = 0; i < time; i++) {
                object x2 = 3;
                var x22 = (int)x2 + 5;
            }
            obj_checker.Stop();
            dy_checker.Start();
            for (int i = 0; i < time; i++) {
                dynamic x1 = 3;
                var x11 = x1 + 5;
            }
            dy_checker.Stop();
            Console.WriteLine("dy:{0}", dy_checker.ElapsedMilliseconds);
            Console.WriteLine("obj:{0}", obj_checker.ElapsedMilliseconds);
            Console.WriteLine("var:{0}", var_checker.ElapsedMilliseconds);
        }
        [TestMethod]
        public void m18() {
            var dy_checker = new Stopwatch();
            var obj_checker = new Stopwatch();
            var time=100*100000;
            obj_checker.Start();
            for (int i = 0; i < time; i++) {
                object x2 = 3;
                var x22 = (int)x2 + 5;
            }
            obj_checker.Stop();
            dy_checker.Start();
            for (int i = 0; i < time; i++) {
                dynamic x1 = 3;
                var x11 = x1 + 5;
            }
            dy_checker.Stop();
            Console.WriteLine("dy:{0}",dy_checker.ElapsedMilliseconds);
            Console.WriteLine("obj:{0}",obj_checker.ElapsedMilliseconds);
        }

测试名称: m18
测试结果: 已通过
结果 StandardOutput:
dy:211
obj:85

测试名称: m19
测试结果: 已通过
结果 StandardOutput:
dy:221
obj:90
var:22

测试名称: m20
测试结果: 已通过
结果 StandardOutput:
dy:302
obj:131

测试名称: m21
测试结果: 已通过
结果 StandardOutput:
dy:224
obj:3057

测试名称: m22
测试结果: 已通过
结果 StandardOutput:
dy:229
obj:43

 ///

结论从性能上考虑, dynamic没有object好,单从装折箱的测试来看,是3.5倍的样子

所以很多使用object的场合 并不一定要换成dyanmic

那么 上面代码中 Test 模仿一下外部加进来的 程序集,在代码执行时 加入的 程序集模块,这种 场景十分常见

这种情况下分两种情况,一种是

有oo设计的 关联的模块,就是 基申明在 调用模块里,比如 基类,或接口等

另一种是,没有oo设计关联的,就是 dynamic的主要价值体现场合,因为在这种情况下 要调用这个模块里的 东西,传统上 只能用object这个 根类通过反映去调用

上面测试对比中已经说明了,与反射 复杂的调用相比,dynamic不仅代码上 简单,而且性能也只有 反射调用的 1/15 

猜你喜欢

转载自www.cnblogs.com/ProjectDD/p/11318823.html