代码之家  ›  专栏  ›  技术社区  ›  Parappa

大写与小写

  •  76
  • Parappa  · 技术社区  · 17 年前

    在进行不区分大小写的比较时,将字符串转换为大写还是小写更有效?这有关系吗?

    建议 in this SO post this argument ToLower与ToUpper的转换取决于字符串中包含更多的内容,通常字符串包含更多的小写字符,这使得ToLower更高效。

    我特别想知道:

    • 有没有一种方法可以优化touper或ToLower,使其中一个比另一个更快?
    • 在大小写字符串之间进行不区分大小写的比较是否更快?为什么?
    10 回复  |  直到 9 年前
        1
  •  93
  •   Jon Skeet    5 年前

    由于某些文化(尤其是土耳其文化)的“有趣”特征,转换为大写或小写以进行不区分大小写的比较是不正确的。相反,使用 StringComparer

    MSDN有一些 great guidelines 关于字符串处理。您可能还希望检查代码是否通过 the Turkey test .

    编辑:注意尼尔的评论 依次的 不区分大小写的比较。整个领域都很模糊:(

        2
  •  29
  •   Ian Boyd    6 年前

    从…起 Microsoft

    Best Practices for Using Strings in the .NET Framework

    为什么?从…起 Microsoft :

    将字符串规范化为大写

    有一小部分字符在转换为小写时无法往返。

    这种角色不能往返的例子是什么?

    • 开始 :希腊Rho符号(U+03f1)
    • 大写:
    • 小写字母:

    , Ρ ρ

    .NET Fiddle

    Original: ϱ
    ToUpper: Ρ
    ToLower: ρ
    

    这就是为什么,如果您想进行不区分大小写的比较,您可以将字符串转换为大写,而不是小写。

    因此,如果你必须选择一个,选择一个 大写字母 .

        3
  •  18
  •   boflynn    9 年前

    根据 MSDN 传入字符串并告诉比较忽略大小写更有效:

    相当于( 但比 )召唤

    Compare(ToUpperInvariant(strA)、ToUpperInvariant(strB)、StringComparison.Ordinal)。

    这些比较仍然很快。

    当然,如果您反复比较一个字符串,那么这可能不成立。

        4
  •  12
  •   warren    5 年前

    在C语言中,或者当使用每个字符串的单独可访问元素(例如C字符串或C++中STL的字符串类型)时,实际上是字节比较——所以比较 UPPER lower .

    如果你鬼鬼祟祟地把你的弦装进 long 相反,您可以对整个字符串进行非常快速的比较,因为它一次可以比较4个字节。但是,加载时间可能会使其不值得。

    为什么你需要知道哪个更快?除非您正在进行一系列比较,否则运行快几个周期的比较与总体执行速度无关,听起来像是过早优化:)

        5
  •  5
  •   Dan Herbert    17 年前

    微软已经进行了优化 ToUpperInvariant() ToUpper() . 不同之处在于,不变量对文化更友好。如果需要对区域性不同的字符串进行不区分大小写的比较,请使用不变量,否则不变量转换的性能应该无关紧要。

    不过,我不能说ToUpper()或ToLower()的速度更快。我从未尝试过,因为我从未遇到过性能如此重要的情况。

        6
  •  4
  •   Apocalisp    17 年前

    如果在C#中进行字符串比较,使用.Equals()比将两个字符串转换为大写或小写要快得多。使用.Equals()的另一大好处是没有为2个新的大写/小写字符串分配更多内存。

        7
  •  3
  •   Zombo tliff    5 年前

    the full list 两字节的 使用 ToLower ToUpper

    using System;
    
    class Program {
       static void Main() {
          char[][] pairs = {
    new[]{'\u00E5','\u212B'},new[]{'\u00C5','\u212B'},new[]{'\u0399','\u1FBE'},
    new[]{'\u03B9','\u1FBE'},new[]{'\u03B2','\u03D0'},new[]{'\u03B5','\u03F5'},
    new[]{'\u03B8','\u03D1'},new[]{'\u03B8','\u03F4'},new[]{'\u03D1','\u03F4'},
    new[]{'\u03B9','\u1FBE'},new[]{'\u0345','\u03B9'},new[]{'\u0345','\u1FBE'},
    new[]{'\u03BA','\u03F0'},new[]{'\u00B5','\u03BC'},new[]{'\u03C0','\u03D6'},
    new[]{'\u03C1','\u03F1'},new[]{'\u03C2','\u03C3'},new[]{'\u03C6','\u03D5'},
    new[]{'\u03C9','\u2126'},new[]{'\u0392','\u03D0'},new[]{'\u0395','\u03F5'},
    new[]{'\u03D1','\u03F4'},new[]{'\u0398','\u03D1'},new[]{'\u0398','\u03F4'},
    new[]{'\u0345','\u1FBE'},new[]{'\u0345','\u0399'},new[]{'\u0399','\u1FBE'},
    new[]{'\u039A','\u03F0'},new[]{'\u00B5','\u039C'},new[]{'\u03A0','\u03D6'},
    new[]{'\u03A1','\u03F1'},new[]{'\u03A3','\u03C2'},new[]{'\u03A6','\u03D5'},
    new[]{'\u03A9','\u2126'},new[]{'\u0398','\u03F4'},new[]{'\u03B8','\u03F4'},
    new[]{'\u03B8','\u03D1'},new[]{'\u0398','\u03D1'},new[]{'\u0432','\u1C80'},
    new[]{'\u0434','\u1C81'},new[]{'\u043E','\u1C82'},new[]{'\u0441','\u1C83'},
    new[]{'\u0442','\u1C84'},new[]{'\u0442','\u1C85'},new[]{'\u1C84','\u1C85'},
    new[]{'\u044A','\u1C86'},new[]{'\u0412','\u1C80'},new[]{'\u0414','\u1C81'},
    new[]{'\u041E','\u1C82'},new[]{'\u0421','\u1C83'},new[]{'\u1C84','\u1C85'},
    new[]{'\u0422','\u1C84'},new[]{'\u0422','\u1C85'},new[]{'\u042A','\u1C86'},
    new[]{'\u0463','\u1C87'},new[]{'\u0462','\u1C87'}
          };
          int upper = 0, lower = 0;
          foreach (char[] pair in pairs) {
             Console.Write(
                "U+{0:X4} U+{1:X4} pass: ",
                Convert.ToInt32(pair[0]),
                Convert.ToInt32(pair[1])
             );
             if (Char.ToUpper(pair[0]) == Char.ToUpper(pair[1])) {
                Console.Write("ToUpper ");
                upper++;
             } else {
                Console.Write("        ");
             }
             if (Char.ToLower(pair[0]) == Char.ToLower(pair[1])) {
                Console.Write("ToLower");
                lower++;
             }
             Console.WriteLine();
          }
          Console.WriteLine("upper pass: {0}, lower pass: {1}", upper, lower);
       }
    }
    

    结果如下。注:我还使用 Invariant 版本,结果是 一模一样。有趣的是,其中一对同时失败。但基于此, 托珀是最好的选择

    U+00E5 U+212B pass:         ToLower
    U+00C5 U+212B pass:         ToLower
    U+0399 U+1FBE pass: ToUpper
    U+03B9 U+1FBE pass: ToUpper
    U+03B2 U+03D0 pass: ToUpper
    U+03B5 U+03F5 pass: ToUpper
    U+03B8 U+03D1 pass: ToUpper
    U+03B8 U+03F4 pass:         ToLower
    U+03D1 U+03F4 pass:
    U+03B9 U+1FBE pass: ToUpper
    U+0345 U+03B9 pass: ToUpper
    U+0345 U+1FBE pass: ToUpper
    U+03BA U+03F0 pass: ToUpper
    U+00B5 U+03BC pass: ToUpper
    U+03C0 U+03D6 pass: ToUpper
    U+03C1 U+03F1 pass: ToUpper
    U+03C2 U+03C3 pass: ToUpper
    U+03C6 U+03D5 pass: ToUpper
    U+03C9 U+2126 pass:         ToLower
    U+0392 U+03D0 pass: ToUpper
    U+0395 U+03F5 pass: ToUpper
    U+03D1 U+03F4 pass:
    U+0398 U+03D1 pass: ToUpper
    U+0398 U+03F4 pass:         ToLower
    U+0345 U+1FBE pass: ToUpper
    U+0345 U+0399 pass: ToUpper
    U+0399 U+1FBE pass: ToUpper
    U+039A U+03F0 pass: ToUpper
    U+00B5 U+039C pass: ToUpper
    U+03A0 U+03D6 pass: ToUpper
    U+03A1 U+03F1 pass: ToUpper
    U+03A3 U+03C2 pass: ToUpper
    U+03A6 U+03D5 pass: ToUpper
    U+03A9 U+2126 pass:         ToLower
    U+0398 U+03F4 pass:         ToLower
    U+03B8 U+03F4 pass:         ToLower
    U+03B8 U+03D1 pass: ToUpper
    U+0398 U+03D1 pass: ToUpper
    U+0432 U+1C80 pass: ToUpper
    U+0434 U+1C81 pass: ToUpper
    U+043E U+1C82 pass: ToUpper
    U+0441 U+1C83 pass: ToUpper
    U+0442 U+1C84 pass: ToUpper
    U+0442 U+1C85 pass: ToUpper
    U+1C84 U+1C85 pass: ToUpper
    U+044A U+1C86 pass: ToUpper
    U+0412 U+1C80 pass: ToUpper
    U+0414 U+1C81 pass: ToUpper
    U+041E U+1C82 pass: ToUpper
    U+0421 U+1C83 pass: ToUpper
    U+1C84 U+1C85 pass: ToUpper
    U+0422 U+1C84 pass: ToUpper
    U+0422 U+1C85 pass: ToUpper
    U+042A U+1C86 pass: ToUpper
    U+0463 U+1C87 pass: ToUpper
    U+0462 U+1C87 pass: ToUpper
    upper pass: 46, lower pass: 8
    
        8
  •  0
  •   Adam Rosenfield    17 年前

    这真的不重要。对于ASCII字符,这绝对不重要——只是一些比较和任意方向的一点翻转。Unicode可能会稍微复杂一些,因为有些字符会以奇怪的方式改变大小写,但除非您的文本中充满了这些特殊字符,否则不会有任何区别。

        9
  •  0
  •   Clearer    16 年前

    如果正确的话,如果你转换成小写,应该会有一个小的、微不足道的速度优势,但正如许多人所暗示的,这是文化相关的,不是在函数中继承的,而是在你转换的字符串中继承的(大量小写字母意味着很少分配给内存)--如果字符串包含大量大写字母,则转换为大写会更快。