代码之家  ›  专栏  ›  技术社区  ›  user113476

.NET中的点有多贵?

  •  2
  • user113476  · 技术社区  · 15 年前

    过去,在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)
    
    6 回复  |  直到 13 年前
        1
  •  26
  •   plinth    13 年前

    这是苹果和桔子的比较。

    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();
    

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

        2
  •  9
  •   Fredrik Mörk    15 年前

    名称空间中的点并不昂贵;它们是由编译器在编译时而不是运行时解析的。(实际上,这是另一种方式,要挑剔;如果使用/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
  •  5
  •   Toad    15 年前

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

    但是,如果你写了:

     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
  •  4
  •   to StackOverflow    15 年前

    它由编译器解决,所以性能是相同的。

        5
  •  1
  •   John Feminella    15 年前

    实际上,在你们两个案例中,我希望结果是相等的。

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

        6
  •  0
  •   Akash Kava    15 年前

    我在我的博客上写了一篇详细的文章,我也有一个基于微秒的计算,但是是的,当你把所有的加起来,你一定能发现不同。

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

    然而,我的文章做了各种计算,它还计算了NamedValueCollection和属性访问时间等。但是理解每件事是如何工作的可能是有用的。