【问题标题】:How expensive are dots in .NET?.NET 中的点有多贵?
【发布时间】:2009-08-27 13:50:30
【问题描述】:

过去,在 C 和 C++ 领域,如果在紧密循环中执行,嵌套指针取消引用被一些人认为是一项相对昂贵的操作。

你不想被抓住:


for (int i = 0; i < 10000000; i++)
{
  j->k->l->m->n->o->p->dosomeworknowthatwereherewhynoteh();
}

因为您可能会损失宝贵的毫秒数。 (是的,我在有点讽刺!)

进入 .NET 世界...

这个更贵吗


System.Runtime.InteropServices.Marshal.WriteInt32(Abort, 1)

比这个?


Imports System.Runtime.InteropServices.Marshal
.
.
.
WriteInt32(Abort, 1)

【问题讨论】:

  • 这不是真正的答案,所以我将其添加为评论。正如您所指出的,您可以做的是编写两个相同的程序,除了 Imports。分别编译,然后查看IL反汇编,并注意和区别。这是最终证明您的理由的一种重要方式。

标签: c# .net vb.net pointers


【解决方案1】:

这是一个苹果和橘子的比较。

System.Runtime.InteropServices.Marshal.WriteInt32(Abort, 1)

在 C++ 中相当于这个:

Foo::Bar::Baz::Func(a, b);

换句话说,命名空间被编译器折叠成零成本。

要得到等价的东西,你可能有这样的东西:

public class Foo {
    public Person Agent { get; }
}

Foo f = getFooFromWhereEver();
f.Agent.Name.ToString().ToLower();

在这种情况下,假设 Person 有一个名为 Name 的属性,它是一个字符串。在这种情况下,点链执行四个方法调用,其中至少一个是虚拟的,但很可能并非所有这些都是不变的,因此多次调用它们是多余的。我说“更有可能......”因为这取决于 Agent 和 Person 的实现。

【讨论】:

  • 你说得对,但我需要一个例子来证明指向同事的指针。谢谢。
  • 添加了更合适的比较。
【解决方案2】:

命名空间中的点并不昂贵;它们由编译器在编译时解析,而不是在运行时解析。 (其实是反过来,挑剔;如果你使用 using/imports 语句来缩短代码,类型引用将在编译时扩展为完整的类型名称,包括命名空间) .但是,到达属性或方法的点确实是有代价的。

这两个应该有相同的性能:

System.Collections.Generic.List<string> myList = new System.Collections.Generic.List<string>();
// using System.Collections.Generic
List<string> myList = new List<string>();

虽然重复访问一个属性的属性可能会花费:

for (int i = 0; i < 100000; i++)
{
    int n = this.ActiveControl.Size.Width;
}
// this should be faster
int width = this.ActiveControl.Size.Width;
for (int i = 0; i < 100000; i++)
{
    int n = width;
}

【讨论】:

  • 编译器几乎总是足够聪明地进行这些优化,但是你的观点是正确的:)
【解决方案3】:

在您的导入示例中,没有区别。导入语句只是确保您不必每次都输入完整的路径。

但是,如果你写的是:

 for(i=0; i<10000; i++)
 {
      classInstance.memberclass.memberclass.memberclass.memberclass.writeInt32(bla);
 }

那么是的,写起来可能会更好:

 SomeClass someclass = classInstance.memberclass.memberclass.memberclass.memberclass;
 for(i=0; i<10000; i++)
 {
      someClass.writeInt32(bla);
 }

【讨论】:

    【解决方案4】:

    由编译器解析,所以性能是一样的。

    【讨论】:

      【解决方案5】:

      实际上,在您的两种情况下,我都希望结果相同。

      在 C 示例中,您实际上是在运行时查看一个对象并取消对它的引用,因此人们认为它是一项昂贵的操作也就不足为奇了。但在 C# 示例中,您所说的“点”是在编译时静态解析的。

      【讨论】:

        【解决方案6】:

        我在我的博客上写了一篇详细的文章,我也有一个基于微秒的计算,但是是的,当你把所有的加起来时,你肯定会有所作为。

        http://akashkava.com/blog/?p=95

        然而我的文章做了各种计算,它也计算了namedvaluecollection和属性访问时间等。但了解一切是如何运作的会很有用。

        【讨论】:

        • 我认为 -ve 点标记肯定应该放置一些 cmets 并显示他们的脸。我欣赏诚实和反馈。
        猜你喜欢
        • 2010-09-29
        • 2011-09-13
        • 2010-12-05
        • 1970-01-01
        • 1970-01-01
        • 2011-12-06
        • 2012-12-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多