C# 为什么.NET String.EqualHelper似乎使用半个整数和长整数

C# 为什么.NET String.EqualHelper似乎使用半个整数和长整数,c#,C#,查看String.EqualsHelper和String.CompareOrdinalHelper(.NET 2&4)的实现,在我看来,比较假设int字节大小为2,长字节大小为4。我认为在.NET 32位世界中,实际大小是4和8。我错过了什么?这里有陷阱吗?和中的源代码示例 反射器反向工程光源(框架2): [可靠性合同(Consistency.WillNotCorruptState,Cer.MayFail)] 私有静态不安全布尔EqualHelper(字符串strA、字符串strB) { 整数长

查看String.EqualsHelper和String.CompareOrdinalHelper(.NET 2&4)的实现,在我看来,比较假设int字节大小为2,长字节大小为4。我认为在.NET 32位世界中,实际大小是4和8。我错过了什么?这里有陷阱吗?和中的源代码示例

反射器反向工程光源(框架2):

[可靠性合同(Consistency.WillNotCorruptState,Cer.MayFail)]
私有静态不安全布尔EqualHelper(字符串strA、字符串strB)
{
整数长度=直线长度;
如果(长度!=strB.长度)
{
返回false;
}
固定(char*str=((char*)strA))
{
char*chPtr=str;
固定(char*str2=((char*)strB))
{
char*chPtr2=str2;
char*chPtr3=chPtr;
char*chPtr4=chPtr2;
而(长度>=10)
{
((((((((((((((((int*))chPtr3((((((((((((((((((((((()()()()()()()()()()(int*))chPtr3(((((((((((((int*)))chPtr3[3)chPtr4())))))除了除了除了除了除了(((((((((((((((((((int*))()()()()()()()()()()()()()()()()()()()()()()()(简称))))))))chPtr3)))chPtr4)(4)(4+4+4+4+4+4+4)()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()(=*((int*)(chPtr4+8(()()))
{
打破
}
chPtr3+=10;
chPtr4+=10;
长度-=10;
}
而(长度>0)
{
如果(*((int*)chPtr3))!=*(((int*)chPtr4)))
{
打破
}
chPtr3+=2;
chPtr4+=2;
长度-=2;
}
返回(长度=10)
{
如果(*((int*)chPtr3))!=*(((int*)chPtr4)))
{
num2=0;
打破
}
如果(*(int*)(chPtr3+2))!=*((int*)(chPtr4+2)))
{
num2=2;
打破
}
如果(*(int*)(chPtr3+4))!=*((int*)(chPtr4+4)))
{
num2=4;
打破
}
如果(*(int*)(chPtr3+6))!=*((int*)(chPtr4+6)))
{
num2=6;
打破
}
如果(*(int*)(chPtr3+8))!=*((int*)(chPtr4+8)))
{
num2=8;
打破
}
chPtr3+=10;
chPtr4+=10;
num-=10;
}
如果(num2==-1)
{
goto标签_0101;
}
chPtr3+=num2;
chPtr4+=num2;
int num3=chPtr3[0]-chPtr4[0];
如果(num3!=0)
{
返回num3;
}
返回(chPtr3[1]-chPtr4[1]);
标签\u 00E7:
如果(*((int*)chPtr3))!=*(((int*)chPtr4)))
{
goto标签_0105;
}
chPtr3+=2;
chPtr4+=2;
num-=2;
标签_0101:
如果(数值>0)
{
转到标签_00E7;
}
标签_0105:
如果(数值>0)
{
int num4=chPtr3[0]-chPtr4[0];
如果(num4!=0)
{
返回num4;
}
返回(chPtr3[1]-chPtr4[1]);
}
返回(strA.Length-strB.Length);
}
}
}
字符是两个字节。 Int是四个字节。 Int比较在一个比较中比较四个字节或两个字符

操作“char\u pointer+2”将char指针增加2个字符或4个字节

单个递增(+4字节)的大小与单个比较(+4字节)的大小相同。

字符是两个字节。 Int是四个字节。 Int比较在一个比较中比较四个字节或两个字符

操作“char\u pointer+2”将char指针增加2个字符或4个字节

单个递增(+4字节)的大小与单个比较(+4字节)的大小相同

这会使指针前进四个字节,两个字符。字符在.NET中是2个字节,它以utf-16编码存储字符。递增一个字符指针会使其前进一个字符,两个字节

这里真正发生的是对int*的转换。这使得算法更快,同时比较两个字符。它在32位cpu上运行良好,它的寄存器足够大,可以容纳两个字符(2 x 16位=32位)。代码中将指针提前10个字符的部分相当于循环展开,这是一种使循环更快的常用优化策略

该算法没有针对64位cpu进行优化,因为64位cpu可以用一条指令同时比较4个字符。当然,这仍然是托管代码,因此可以编译为32位或64位机器代码,具体取决于它运行的cpu类型

这会使指针前进四个字节,两个字符。字符在.NET中是2个字节,它以utf-16编码存储字符。递增一个字符指针会使其前进一个字符,两个字节

这里真正发生的是对int*的转换。这使得算法更快,同时比较两个字符。它在32位cpu上运行良好,它的寄存器足够大,可以容纳两个字符(2 x 16位=32位)。代码中将指针提前10个字符的部分相当于循环展开,这是一种使循环更快的常用优化策略

该算法没有针对64位cpu进行优化,因为64位cpu可以用一条指令同时比较4个字符。当然,这仍然是托管代码,因此可以编译为32位或64位机器代码,具体取决于它运行的cpu类型。

是的,我认为这是
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
private static unsafe bool EqualsHelper(string strA, string strB)
{
    int length = strA.Length;
    if (length != strB.Length)
    {
        return false;
    }
    fixed (char* str = ((char*) strA))
    {
        char* chPtr = str;
        fixed (char* str2 = ((char*) strB))
        {
            char* chPtr2 = str2;
            char* chPtr3 = chPtr;
            char* chPtr4 = chPtr2;
            while (length >= 10)
            {
                if ((((*(((int*) chPtr3)) != *(((int*) chPtr4))) || (*(((int*) (chPtr3 + 2))) != *(((int*) (chPtr4 + 2))))) || ((*(((int*) (chPtr3 + 4))) != *(((int*) (chPtr4 + 4)))) || (*(((int*) (chPtr3 + 6))) != *(((int*) (chPtr4 + 6)))))) || (*(((int*) (chPtr3 + 8))) != *(((int*) (chPtr4 + 8)))))
                {
                    break;
                }
                chPtr3 += 10;
                chPtr4 += 10;
                length -= 10;
            }
            while (length > 0)
            {
                if (*(((int*) chPtr3)) != *(((int*) chPtr4)))
                {
                    break;
                }
                chPtr3 += 2;
                chPtr4 += 2;
                length -= 2;
            }
            return (length <= 0);
        }
    }
}

private static unsafe int CompareOrdinalHelper(string strA, string strB)
{
    int num = Math.Min(strA.Length, strB.Length);
    int num2 = -1;
    fixed (char* str = ((char*) strA))
    {
        char* chPtr = str;
        fixed (char* str2 = ((char*) strB))
        {
            char* chPtr2 = str2;
            char* chPtr3 = chPtr;
            char* chPtr4 = chPtr2;
            while (num >= 10)
            {
                if (*(((int*) chPtr3)) != *(((int*) chPtr4)))
                {
                    num2 = 0;
                    break;
                }
                if (*(((int*) (chPtr3 + 2))) != *(((int*) (chPtr4 + 2))))
                {
                    num2 = 2;
                    break;
                }
                if (*(((int*) (chPtr3 + 4))) != *(((int*) (chPtr4 + 4))))
                {
                    num2 = 4;
                    break;
                }
                if (*(((int*) (chPtr3 + 6))) != *(((int*) (chPtr4 + 6))))
                {
                    num2 = 6;
                    break;
                }
                if (*(((int*) (chPtr3 + 8))) != *(((int*) (chPtr4 + 8))))
                {
                    num2 = 8;
                    break;
                }
                chPtr3 += 10;
                chPtr4 += 10;
                num -= 10;
            }
            if (num2 == -1)
            {
                goto Label_0101;
            }
            chPtr3 += num2;
            chPtr4 += num2;
            int num3 = chPtr3[0] - chPtr4[0];
            if (num3 != 0)
            {
                return num3;
            }
            return (chPtr3[1] - chPtr4[1]);
        Label_00E7:
            if (*(((int*) chPtr3)) != *(((int*) chPtr4)))
            {
                goto Label_0105;
            }
            chPtr3 += 2;
            chPtr4 += 2;
            num -= 2;
        Label_0101:
            if (num > 0)
            {
                goto Label_00E7;
            }
        Label_0105:
            if (num > 0)
            {
                int num4 = chPtr3[0] - chPtr4[0];
                if (num4 != 0)
                {
                    return num4;
                }
                return (chPtr3[1] - chPtr4[1]);
            }
            return (strA.Length - strB.Length);
        }
    }
}
chPtr3 += 2;