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

有时候我们需要对字符串进行修改,但是.net里面的字符串是只读的,修改动作会产生一个新的字符串,多数时候这都不是我想要的结果。不过fixed还是可以帮我们解决一部分问题的,比如.ToLower、.ToUpper、.Replace(char, char)等等,不过有个限制,就是变换前后的字符串长度不变。

        public unsafe static string toLower(this string value)
        {
            if (value != null)
            {
                fixed (char* valueFixed = value) toLowerUnsafe(valueFixed, valueFixed + value.Length);
            }
            return value;
        }
        public unsafe static void toLower(char* start, char* end)
        {
            if (start != null && end > start) toLowerUnsafe(start, end);
        }
        public unsafe static void toLowerUnsafe(char* start, char* end)
        {
            while (start != end)
            {
                if ((uint)(*start - 'A') < 26) *start |= (char)0x20;
                ++start;
            }
        }
        public unsafe static string toUpper(this string value)
        {
            if (value != null)
            {
                fixed (char* valueFixed = value) toUpperUnsafe(valueFixed, valueFixed + value.Length);
            }
            return value;
        }
        public unsafe static void toUpper(char* start, char* end)
        {
            if (start != null && end > start) toUpperUnsafe(start, end);
        }
        public unsafe static void toUpperUnsafe(char* start, char* end)
        {
            while (start != end)
            {
                if ((uint)(*start - 'a') < 26) *start -= (char)0x20;
                ++start;
            }
        }
        public static string replace(this string value, char oldChar, char newChar)
        {
            return value != null && value.Length != 0 ? replaceUnsafe(value, oldChar, newChar) : null;
        }
        public unsafe static string replaceNotNull(this string value, char oldChar, char newChar)
        {
            return value.Length != 0 ? replaceUnsafe(value, oldChar, newChar) : value;
        }
        public unsafe static string replaceUnsafe(this string value, char oldChar, char newChar)
        {
            fixed (char* valueFixed = value)
            {
                char* start=valueFixed, end = valueFixed + value.Length;
                char endValue = *--end;
                *end = oldChar;
                do
                {
                    while (*start != oldChar) ++start;
                    *start = newChar;
                }
                while (start++ != end);
                if (endValue != oldChar) *end = endValue;
            }
            return value;
        }

Release实测,效果还不错,英文大小写转换运行时间降到了.ToLower与.ToUpper的1/4以下,字符替换运行时间降到了.Replace(char, char)的1/5以下,同时给垃圾回收也减少了很多压力。当然.ToLower与.ToUpper还是比较强大的,它不仅仅只是英文转换,但是我个人只处理过英文大小写问题。
需要注意的是,这里是直接修改字符串的数据,会影响到所有相关引用,如果对影响程度没有把握,一般建议应用在一次性的临时变量上。这里只是举几个例子,具体其它可能的字符串修改应用就需要你自己却发掘了。

posted on 2012-05-10 16:26  肖进  阅读(1815)  评论(3编辑  收藏  举报