2012年5月8日星期二

字符串的字典序比较

字符串的字典序比较

字典序比较.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%,关键是满足了新的功能需求,提高了其他程序的运行效率。


TAG:字符串 比较 性能