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

伊利诺伊州的ldsfld和ldstr有什么不同?

  •  8
  • David  · 技术社区  · 14 年前

    我读过一些关于string.empty vs“”的文章,我自己也做过测试。它们之间的区别如下。

    空字符串

    L_0001: ldsfld string [mscorlib]System.String::Empty
    

    L_0001: ldstr ""
    

    在我和朋友们交谈之后,他们认为string.empty比“”更快,因为在引擎盖下(在装配级别),ldstr比ldsfld做1个以上的循环。(我记不起使它们与众不同的步骤)

    我想知道如何检查这方面的性能。

    3 回复  |  直到 12 年前
        1
  •  13
  •   Guffa    14 年前

    这个 ldsfld 操作将静态字段的值推送到计算堆栈上,而 ldstr 推送对元数据字符串文字的引用。

    性能差异(如果有)将是最小的。编译器的新版本实际上替代了 "" 对于 String.Empty .

    您还应该考虑代码的可读性和可维护性。使用 空字符串 更清楚的是,您实际上是指空字符串,而不仅仅是忘记了在字符串文本中键入内容。

    编辑:

    我查看了创建的本机代码。

    C 3,发布模式,x86:

            string a = String.Empty;
    0000002a  mov         eax,dword ptr ds:[0356102Ch]
    0000002f  mov         dword ptr [ebp-8],eax
            string b = "";
    00000032  mov         eax,dword ptr ds:[0356202Ch]
    00000038  mov         dword ptr [ebp-0Ch],eax
    

    C 3,释放模式,X64:

            string a = String.Empty;
    0000003b  mov         rax,12711050h 
    00000045  mov         rax,qword ptr [rax] 
    00000048  mov         qword ptr [rsp+28h],rax 
            string b = "";
    0000004d  mov         rax,12713048h 
    00000057  mov         rax,qword ptr [rax] 
    0000005a  mov         qword ptr [rsp+30h],rax 
    

    所以,最终代码是相同的。

        2
  •  7
  •   Jon Skeet    14 年前

    ldstr 是从元数据加载特定字符串标记的IL。

    ldsfld 是IL以加载指定的 领域 -在这种情况下 string.Empty .

    换句话说,它们是完全不同的操作,在本例中恰好有相同的结果。它们是如何在组装级别实现的?好吧,这很可能取决于您使用的CLR版本。问你的朋友他们说的是哪种版本…桌面(32或64位?1,2,2sp1,2sp2,4?),压缩框架(同样,哪个版本?),Silverlight(哪个操作系统,哪个版本?)他们用过了吗? cordbg 关于您实际讨论的代码,或者他们是在一些示例代码上做的,这些示例代码可能没有以相同的方式进行优化?

    我会(并且已经)争辩说,你应该使用任何你觉得更可读的。我个人更喜欢 "" 但其他人更喜欢 空字符串 . 那很好。为了一个一个地争论性能的原因需要 证据 虽然…理想情况下,基于您实际编写的代码的证据,而不是微观基准。

    我会 惊讶的 要了解代码,这两个代码之间的任何差异实际上会导致实际代码的性能显著差异,而不是在无论如何都有更好的方法来处理任务的情况下。

        3
  •  7
  •   Marc Gravell    12 年前

    从.NET 4.5差异 在这种情况下 是:完全没有。现在看来,JIT检测到了这个ldsfld,并直接注入插入的空字符串。

    您可以这么说,因为在<4.5中,您可以通过反射更改string.empty的值,它会影响使用string.empty的代码。讨厌但可能。从4.5开始,这不再有效。如果您可以通过反射进行检查,您将得到黑客版本,但使用string.empty via ldsfld的代码将得到正确的空字符串,而不是黑客版本。

    推荐文章