c# - 为什么 .NET string.Equals 每个循环检查 5 个字符?(AMD 为 6)
问题描述
在查看 .Net 源代码时发现了一件奇怪的事情String
。在Equals
帮助器中:
https ://referencesource.microsoft.com/#mscorlib/system/string.cs,11648d2d83718c5e ,用于检查字符串相等性的引用,它一次检查四个字节(我认为),但循环的每次迭代都会五个检查,每个进步两个位置。(并且为 AMD 做了六个,这也很奇怪)
我假设这是他们已经完成的一些特定的微优化,但为什么在循环中检查五次而不是循环五次更快?
感觉我解释的不是很好,但是出处在链接里,会更好的解释。
private unsafe static bool EqualsHelper(String strA, String strB)
{
Contract.Requires(strA != null);
Contract.Requires(strB != null);
Contract.Requires(strA.Length == strB.Length);
int length = strA.Length;
fixed (char* ap = &strA.m_firstChar) fixed (char* bp = &strB.m_firstChar)
{
char* a = ap;
char* b = bp;
// unroll the loop
#if AMD64
// for AMD64 bit platform we unroll by 12 and
// check 3 qword at a time. This is less code
// than the 32 bit case and is shorter
// pathlength
while (length >= 12)
{
if (*(long*)a != *(long*)b) return false;
if (*(long*)(a+4) != *(long*)(b+4)) return false;
if (*(long*)(a+8) != *(long*)(b+8)) return false;
a += 12; b += 12; length -= 12;
}
#else
while (length >= 10)
{
if (*(int*)a != *(int*)b) return false;
if (*(int*)(a+2) != *(int*)(b+2)) return false;
if (*(int*)(a+4) != *(int*)(b+4)) return false;
if (*(int*)(a+6) != *(int*)(b+6)) return false;
if (*(int*)(a+8) != *(int*)(b+8)) return false;
a += 10; b += 10; length -= 10;
}
#endif
// This depends on the fact that the String objects are
// always zero terminated and that the terminating zero is not included
// in the length. For odd string sizes, the last compare will include
// the zero terminator.
while (length > 0)
{
if (*(int*)a != *(int*)b) break;
a += 2; b += 2; length -= 2;
}
return (length <= 0);
}
}
解决方案
推荐阅读
- javascript - 基于两个对象数组创建html表:一个包含数据,另一个包含列(包括数据数组属性名称)
- java - 无法解析“FirebaseRemoteConfig”中的方法“activateFetched”
- botframework - 我在哪里可以获得 LuisAPIKey 和 LuisAPIHostName?
- c - 从堆栈中删除的函数内部的变量如何在内存中表现
- typescript - typescript 接口给出 typeerror
- javascript - 在 React 底部时元素没有被加载?
- android - 在安卓中分享视频
- c# - C# 从 swagger.json 生成类作为构建的一部分
- c# - 从 c# Forms 应用程序运行批处理文件和命令
- computer-vision - simpledet 库 create_coco_roidb 错误