CLR字符串索引器如何工作?

时间:2012-07-16 13:31:09

标签: string clr

comment buried in some C++ code声明中的SSCLI,指的是String.Chars属性的非托管内部实现:

  

实际上并未使用此方法。 JIT将为字符串类生成索引器方法的代码。

那么...... 是什么神奇的代码呢?我理解抖动的全部意义在于它们在不同情况下产生不同的代码。但至少,对于现代的x64 Windows 7+平台,/ a jitter如何实现这一目标呢?或者这是真正的秘密酱油?

其他详情

前段时间我正在寻找fastest way to iterate through individual characters in a string in C#。 事实证明,这是最快的方法,无需使用不安全的代码或复制内容(通过ToCharArray()) 是内置的字符串索引器,它实际上是对String.Chars property的调用。就在我原来的 问题我问是否有人能够深入了解索引器的实际工作情况,但是尽管Skeet和 Lippert,我没有得到任何回应。所以我决定自己深入研究:

停止1:mscorlib

通过使用ildasm检查mscorlib.dll,我们可以看到String::get_Chars(int32 index)只是一个internalcall指针(加上一个属性):

.method public hidebysig specialname instance char 
        get_Chars(int32 index) cil managed internalcall
{
  .custom instance void System.Security.SecuritySafeCriticalAttribute::.ctor() = ( 01 00 00 00 ) 
} // end of method String::get_Chars

documentation for the MethodImplOptions enumeration中所述,“内部调用是对在公共语言运行时本身内实现的方法的调用。” 2004 MSDN Magazine articleSO post都表示internalcall名称与非托管实现的映射可以在Shared Source CLI内的ecall.cpp中找到。

停止2:ecapp.cpp

搜索online copy of ecall.cpp表明get_Chars已由COMString::GetCharAt实施:

FCIntrinsic("get_Chars", COMString::GetCharAt, CORINFO_INTRINSIC_StringGetChar)

停止3:comstring.cpp

comstring.cpp确实包含GetCharAt的实现,从第1219行开始。除此之外,它之前是此注释:

/*==================================GETCHARAT===================================
**Returns the character at position index.  Thows IndexOutOfRangeException as
**appropriate.
**This method is not actually used. JIT will generate code for indexer method on string class.
**
==============================================================================*/

1 个答案:

答案 0 :(得分:1)

首先,请参阅Hans Passant对关键位的评论。

在早期的.NET(CLR 1和2)中,CLR对StringStringBuilder类型提供了相当多的特殊支持。事实上,这两种类型的工作非常紧密,StringBuilder.ToString没有在任何地方复制实际字符,字符串索引器仍然使用特殊的抖动支持从相同的内存位置获取字符。我假设对String.Chars的抖动支持最初是必要的,以避免通过堆栈传递索引整数,但从那时起抖动似乎有improved

.NET 4带有StringBuilder (ropes)的不同实现,不再与String的处理方式相关联。 (它必须在ToString期间复制,但附加速度要快得多。)经过这些更改后,

  • StringBuilder索引器在大字符串上显着减慢到 O(log n)See here。它永远不会内联,甚至不会在短字符串中。
  • String索引器仍然使用(未发布)特殊抖动支持。我希望这个基本上可以转换为移位,添加和内存提取,或者更接近最近的循环允许的更快。