gpt4 book ai didi

c# - 为什么后续的直接方法调用比第一次调用快很多?

转载 作者:太空狗 更新时间:2023-10-29 18:20:52 25 4
gpt4 key购买 nike

this MSDN article 中所述,当使用诸如 InvokeMember 之类的 .NET 反射 API 时,由于元数据的缓存,第一次调用比后续调用花费更多的时间来运行。

当我测试不使用反射的直接方法调用时,我在 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}", value1, time1);
Console.WriteLine("{0} - {1}", value2, time2);
Console.WriteLine("{0} - {1}", value3, time3);
}
static void Main()
{
DirectTest();
DirectTest();
}
}

最佳答案

这是因为 Just In Time (JIT)用于 .NET 应用程序的编译方法。 MSIL bytecode由 JIT 编译器一次翻译成机器代码,并且该代码的后续执行速度要快得多,因为已经生成并缓存了 native 版本。

您在运行代码时会付出一次性代价,但 JIT 编译器还可以针对当前架构执行优化,如果代码从一开始就是原生的,则无法执行这些优化。但是,您可以通过调用 RuntimeHelpers.PrepareMethod. 来强制执行 JIT pass

关于c# - 为什么后续的直接方法调用比第一次调用快很多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6417598/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com