c# – 为什么后续的直接方法调用比第一次调用要快得多?
发布时间:2020-12-15 03:53:10 所属栏目:百科 来源:网络整理
导读:正如在 this MSDN article中所解释的,当使用诸如InvokeMember之类的.NET Reflection API时,由于元数据的缓存,第一次调用比后续调用花费更多的时间. 当我在不使用Reflection的情况下测试直接方法调用时,我也看到了对Mono和.NET 4的类似效果. 第一个数字是操作
正如在
this MSDN article中所解释的,当使用诸如InvokeMember之类的.NET Reflection API时,由于元数据的缓存,第一次调用比后续调用花费更多的时间.
当我在不使用Reflection的情况下测试直接方法调用时,我也看到了对Mono和.NET 4的类似效果. 第一个数字是操作的结果,“ – ”后面的第二个数字是以ms为单位的此操作所花费的时间.我使用’< - '标记来标识第一个方法调用. 300 - 0.192 <-- 300 - 0.004 300 - 0.004 -100 - 0.096 <-- -100 - 0.004 -100 - 0.004 为什么是这样?我可以理解第一次调用可能比较慢,但速度慢50倍并不是我的预期. 附件是获得此结果的源代码. 图书馆 namespace MyClass { public class Calculator { public int Value1 {get; set;} public int Value2 {get; set;} public Calculator() { Value1 = 100; Value2 = 200; } public int Add(int val1,int val2) { Value1 = val1; Value2 = val2; return Value1 + Value2; } public int Sub(int val1,int val2) { Value1 = val1; Value2 = val2; return Value1 - Value2; } } } 调用此库的代码 // http://msdn.microsoft.com/en-us/magazine/cc163759.aspx using System; using System.IO; using System.Reflection; using System.Diagnostics; using System.Collections.Generic; using MyClass; class TestOne { static void DirectTest() { Stopwatch sw; Calculator t = new Calculator(); sw = Stopwatch.StartNew(); int value1 = t.Add(100,200); sw.Stop(); double time1 = sw.Elapsed.TotalMilliseconds; sw = Stopwatch.StartNew(); int value2 = t.Add(100,200); sw.Stop(); double time2 = sw.Elapsed.TotalMilliseconds; sw = Stopwatch.StartNew(); int value3 = t.Add(100,200); sw.Stop(); double time3 = sw.Elapsed.TotalMilliseconds; Console.WriteLine("{0} - {1}",value1,time1); Console.WriteLine("{0} - {1}",value2,time2); Console.WriteLine("{0} - {1}",value3,time3); sw = Stopwatch.StartNew(); value1 = t.Sub(100,200); sw.Stop(); time1 = sw.Elapsed.TotalMilliseconds; sw = Stopwatch.StartNew(); value2 = t.Sub(100,200); sw.Stop(); time2 = sw.Elapsed.TotalMilliseconds; sw = Stopwatch.StartNew(); value3 = t.Sub(100,200); sw.Stop(); time3 = sw.Elapsed.TotalMilliseconds; Console.WriteLine("{0} - {1}",time3); } static void Main() { DirectTest(); DirectTest(); } } 解决方法
这是因为用于.NET应用程序的
Just In Time (JIT)编译方法. J001编译器将
MSIL bytecode转换为机器代码,并且后续执行该代码的速度要快得多,因为已生成并缓存了本机版本.
运行代码时,您需要支付一次罚款,但JIT编译器还可以对当前体系结构执行优化,如果代码是从一开始就是本机代码,则无法执行该优化.但是,您可以通过调用RuntimeHelpers.PrepareMethod.强制执行JIT传递 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |