【问题标题】:Speed Issues with delegates and Structs代表和结构的速度问题
【发布时间】:2011-11-10 21:17:13
【问题描述】:

我在结构和委托方面遇到了一些速度问题 - 使用以下控制台应用程序代码:

public delegate string StringGetter();
public class LocalString
{
    public LocalString(string value)
    {
        this.value = value;
    }

    public StringGetter Getter
    {
        get
        {
            return new StringGetter(this.GetValue);
        }
    }

    private string GetValue()
    {
        return value;
    }

    private string value;
}


class Program
{
    static void Main(string[] args)
    {
        var start = DateTime.Now;
        for (int i = 0; i < 2000000; i++)
        {
            var val = new LocalString( "hello World" );
            val.Getter();
        }
        Console.WriteLine((DateTime.Now - start).TotalMilliseconds);
        Console.ReadKey();
    }
}

在我的机器上执行时大约需要 1.8 秒...如果我将结构更改为一个类,它将在大约 0.1 秒内运行。我查看了底层汇编代码和开源 ROTOR 代码以了解原因,并且有一些特殊代码用于具有结构目标的委托,我猜这些代码用于处理函数 MethodDesc* COMDelegate:: 中的装箱和拆箱: GetDelegateCtor(TypeHandle delegateType, MethodDesc *pTargetMethod, DelegateCtorArgs *pCtorData)。

另一点 - 如果您在 VS2008 中针对 .net 3.5 构建此应用程序,则应用程序运行速度比在针对 .net 3.5 的 VS2010 中运行它更快。我还没弄清楚这是为什么。

欢迎任何 cmets / 更好的启蒙......

问候 李

【问题讨论】:

  • 这个例子是部分设计的(有些是从真实代码中提取的)只是为了重现这个问题。诚然,我本可以进一步减少它,但它确实可以编译和运行。
  • @leppie:我建议你实际上尝试编译它,然后重新评估你的位置......
  • @WillemvanRumpt:我承认。 :) 但问题是为什么要使用 new StringGetter(somestringgetter) 而不是 instance.Getter ?事实上,我觉得奇怪的是委托有这样的构造函数(采用相同类型的委托)。我认为这种“魔法”没有任何意义。
  • 澄清我的观点:var k = new Action(new Action( new Action (K))); 是有效的,完全是血腥可怕的代码。
  • @leppie:哦,我们可以同意代码的高白板尖叫值:)

标签: .net performance delegates struct


【解决方案1】:

这很难准确回答,代表的 CLR 支持代码是一个难以破解的难题。我最好的猜测是取消/装箱结构值所需的开销。委托调用是通过一个存根进行的,该存根首先将值装箱,以便可以调用实例方法。调用后,该方法的任何副作用都需要复制回原始结构。与对引用类型的实例方法的简单调用相比,这很昂贵,它们非常快。我没有看到任何验证结构值活性的证据,有点奇怪,但很可能在某个地方。

【讨论】:

  • 听起来对我来说是一个很好的解释!它仍然留下一个问题,为什么使用 2010 .net v3.5 构建的 exe 比 VS2008 .net v3.5 生成的 exe 稍慢...无论如何,答案很好,干杯!
  • 如果您确定它们都在同一个 .Net 上运行,那么唯一的区别可能在于 IL。您可以使用 Reflector 或 ildasm 等工具轻松检查。
猜你喜欢
  • 2012-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多