VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > Objective-C编程 >
  • c#4.01之Bate2改进之全新的Dynamic

制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
 

  在C#4.0 b1中,dynamic的出现得到了很多人的关注,该关键字的出现能大幅改进某些情况下的开发效率,但是,通过大家对比测试,该方式同时也会带来很大的性能损失,方法的执行不过是对反射执行的封装,远不如使用Emit或者Expression编译委托来得快.但是在最新的C# 4.0 beta2中,dynamic的实现的得到了很大的改变.

  首先使用测试程序对比下几种常见的方法调用.程序分别将对直接调用,传统反射调用,dynamic调用,expression调用,emit调用速度进行简单的对比,该对比程序只调用一个空方法,纯测试方法调用的耗时,如果测试有什么问题,欢迎提出.

  下面给出测试主程序的源代码(完整代码见文后附带源码):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace DynamicTest {
    class Program {
        static void Main(string[] args) {
            TestClass staticInstanse = new TestClass();
            dynamic dynamicInstanse = staticInstanse;
            int num = 100000; //次数
            var expressionFun = staticInstanse.GetExpressionCallFunction("TestMethod");
            var emitFun = staticInstanse.GetEmitCallFunction("TestMethod");
            var method = staticInstanse.GetType().GetMethod("TestMethod");
            Console.WriteLine("开始对比测试(连续执行{0}次空方法):", num);
            Stopwatch watch = new Stopwatch();
            //测试直接调用
            watch.Start();
            for (int i = 0; i < num; i++) {
                staticInstanse.TestMethod();
            }
            watch.Stop();
            Console.WriteLine("直接调用耗时:{0} ms", watch.Elapsed.TotalMilliseconds);
            //测试反射调用
            watch.Reset();
            watch.Start();
            for (int i = 0; i < num; i++) {
                method.Invoke(staticInstanse, null);
            }
            watch.Stop();
            Console.WriteLine("使用反射调用耗时:{0} ms", watch.Elapsed.TotalMilliseconds);
            //测试包含首次调用的dynamic调用
            watch.Reset();
            watch.Start();
            for (int i = 0; i < num; i++) {
                dynamicInstanse.TestMethod();
            }
            watch.Stop();
            Console.WriteLine("使用包含首次调用的dynamic调用耗时:{0} ms", watch.Elapsed.TotalMilliseconds);
            //测试出去首次调用后的dynamic调用
            watch.Reset();
            watch.Start();
            for (int i = 0; i < num; i++) {
                dynamicInstanse.TestMethod();
            }
            watch.Stop();
            Console.WriteLine("使用去掉首次调用的dynamic调用耗时:{0} ms", watch.Elapsed.TotalMilliseconds);
            //测试expression调用
            watch.Reset();
            watch.Start();
            for (int i = 0; i < num; i++) {
                expressionFun(staticInstanse);
            }
            watch.Stop();
            Console.WriteLine("使用Expression调用耗时:{0} ms", watch.Elapsed.TotalMilliseconds);
            //测试emit调用
            watch.Reset();
            watch.Start();
            for (int i = 0; i < num; i++) {
                emitFun(staticInstanse);
            }
            watch.Stop();
            Console.WriteLine("使用Emit调用耗时:{0} ms", watch.Elapsed.TotalMilliseconds);
        }
    }
}

 

  通过测试,最后得到的结果如下(测试结果进代表本人机器测试结果,其他机器可能会有不同,但是相信相对的的速度对比值应该一致):

  C# 4.0 Beta2改进之全新的dynamic

  通过测试可以得到以下的大致结果:

  直接调用最快

  使用emit调用其次,大概是直接调用的10倍左右

  Expression调用再次,然后是dynamic调用,不过很明显,dynamic的第一次调用速度比较慢,去掉第一次的执行之后,dynamic已经和expression调用的时间相差不大,当然最慢的是传统反射调用,远远低于其他的调用方式.

  在此可以看出,dynamic的实现相比b1中得到了极大的改善,已经能满足绝大多数使用情况.

  我们可以通过Reflector来查看目前dynamic的实现方式:

  C# 4.0 Beta2改进之全新的dynamic

  图片看不清楚?请点击这里查看原图(大图)。

  很明显,dynamic不再是传统的反射调用,个人猜测也是采用通过某种方式编译成委托的方式进行调用,所以能使得性能得到了极大的提高.

 

  本文示例源代码或素材下载

 

  通过测试,最后得到的结果如下(测试结果进代表本人机器测试结果,其他机器可能会有不同,但是相信相对的的速度对比值应该一致):

  C# 4.0 Beta2改进之全新的dynamic

  通过测试可以得到以下的大致结果:

  直接调用最快

  使用emit调用其次,大概是直接调用的10倍左右

  Expression调用再次,然后是dynamic调用,不过很明显,dynamic的第一次调用速度比较慢,去掉第一次的执行之后,dynamic已经和expression调用的时间相差不大,当然最慢的是传统反射调用,远远低于其他的调用方式.

  在此可以看出,dynamic的实现相比b1中得到了极大的改善,已经能满足绝大多数使用情况.

  我们可以通过Reflector来查看目前dynamic的实现方式:

  C# 4.0 Beta2改进之全新的dynamic

  图片看不清楚?请点击这里查看原图(大图)。

  很明显,dynamic不再是传统的反射调用,个人猜测也是采用通过某种方式编译成委托的方式进行调用,所以能使得性能得到了极大的提高.

 

  本文示例源代码或素材下载


相关教程