C#效率极子 - 精益求精
自动化+性能优化

字典序比较.net类库自带有string.CompareOrdinal,不过不支持char*。有时候为了效率不想重复fixed同一个字符串,而却有时候char*是stackalloc new出来的,更加不适应。还是那句话,自食其力吧。

        public static unsafe int cmp(string left, string right)
        {
            if (left != null && right != null)
            {
                int length = left.Length <= right.Length ? left.Length : right.Length;
                for (int index = 0, endIndex = Math.Min(length, 4); index != endIndex; ++index)
                {
                    int value = left[index] - right[index];
                    if (value != 0) return value;
                }
                if ((length -= 4) > 0)
                {
                    fixed (char* leftFixed = left, rightFixed = right)
                    {
                        int value = Cmp(leftFixed + 4, rightFixed + 4, length);
                        if (value != 0) return value;
                    }
                }
                return left.Length - right.Length;
            }
            if (left == right) return 0;
            return left != null ? 1 : -1;
        }
        private static unsafe int Cmp(char* left, char* right, int length)
        {
            while (length >= 8)
            {
                if (((*(uint*)left ^ *(uint*)right) | (*(uint*)(left + 4) ^ *(uint*)(right + 4))
                    | (*(uint*)(left + 8) ^ *(uint*)(right + 8)) | (*(uint*)(left + 12) ^ *(uint*)(right + 12))) != 0)
                {
                    if (((*(uint*)left ^ *(uint*)right) | (*(uint*)(left + 4) ^ *(uint*)(right + 4))) == 0)
                    {
                        left += 8;
                        right += 8;
                    }
                    if (*(uint*)left == *(uint*)right)
                    {
                        left += 4;
                        right += 4;
                    }
                    int value = (int)*(ushort*)left - *(ushort*)right;
                    return value == 0 ? (int)*(ushort*)(left += 2) - *(ushort*)(right += 2) : value;
                }
                length -= 8;
                left += 16;
                right += 16;
            }
            if ((length & 4) != 0)
            {
                if (((*(uint*)left ^ *(uint*)right) | (*(uint*)(left + 4) ^ *(uint*)(right + 4))) != 0)
                {
                    if ((*(uint*)left ^ *(uint*)right) == 0)
                    {
                        left += 4;
                        right += 4;
                    }
                    int value = (int)*(ushort*)left - *(ushort*)right;
                    return value == 0 ? (int)*(ushort*)(left += 2) - *(ushort*)(right += 2) : value;
                }
                left += 8;
                right += 8;
            }
            if ((length & 2) != 0)
            {
                int code = (int)*(ushort*)left - *(ushort*)right;
                if (code != 0) return code;
                code = (int)*(ushort*)(left + 2) - *(ushort*)(right + 2);
                if (code != 0) return code;
                left += 4;
                right += 4;
            }
            return (length & 1) == 0 ? 0 : ((int)*(ushort*)left - *(ushort*)right);
        }

Release实测,运行效率不算很糟糕,一般情况还能比string.CompareOrdinal快20%-40%,关键是满足了新的功能需求,提高了其他程序的运行效率。

posted on 2012-05-08 11:57  肖进  阅读(1662)  评论(0编辑  收藏  举报