C# 修剪字符串并将其转换为小写的最快方法

C# 修剪字符串并将其转换为小写的最快方法,c#,.net,windows,C#,.net,Windows,我已经编写了一个处理字符串的类,但我有以下问题:传入的字符串可能在字符串的开头和结尾都带有空格 我需要修剪字符串中的空格,并将其转换为小写字母。到目前为止,我的代码是: var searchStr = wordToSearchReplacemntsFor.ToLower(); searchStr = searchStr.Trim(); 我在StringBuilder中找不到任何函数来帮助我。问题是这个类应该尽可能快地处理大量字符串。所以我不想为类处理的每个字符串创建2个新字符串

我已经编写了一个处理字符串的类,但我有以下问题:传入的字符串可能在字符串的开头和结尾都带有空格

我需要修剪字符串中的空格,并将其转换为小写字母。到目前为止,我的代码是:

var searchStr = wordToSearchReplacemntsFor.ToLower();
        searchStr = searchStr.Trim();
我在
StringBuilder
中找不到任何函数来帮助我。问题是这个类应该尽可能快地处理大量字符串。所以我不想为类处理的每个字符串创建2个新字符串

如果这是不可能的,我将深入研究处理算法。

尝试方法链接

例:


首先,修剪第一个,替换第二个,所以你必须用ToLower()遍历一个较小的字符串

除此之外,我认为您最好的算法如下所示:

  • 在字符串上迭代一次,然后检查
    • 是否有大写字符
    • 开头和结尾是否有空格(并计算您正在谈论的字符数)
  • 如果以上都没有,则返回原始字符串
  • 如果是大写但没有空格:do ToLower并返回
  • 如果空白:
    • 分配一个大小正确的新字符串(原始长度-白色字符数)
    • 在做托洛尔的时候把它填上

    • 赛博德鲁的想法是正确的。由于字符串是不可变的,您将在这两个调用期间分配内存。如果要在代码中的许多位置调用
      string.Trim().ToLower()
      ,我想建议一件事,就是使用以下命令简化调用。例如:

      public static class MyExtensions
      {
          public static string TrimAndLower(this String str)
          {
              return str.Trim().ToLower();
          }
      }   
      

      如果字符串仅使用ASCII字符,则可以查看。如果您提前知道字符集,您也可以尝试使用。但在我登记之前,我会问两个非常重要的问题

    • 连续的“String.Trim”和“String.ToLower”调用真的会影响我的应用程序的性能吗?有人注意到这个算法是慢了一倍还是快了一倍吗?知道的唯一方法是测量代码的性能,并与预先设定的性能目标进行比较。否则,微观优化将产生微观性能增益

    • 仅仅因为我写了一个看起来更快的实现,并不意味着它真的更快。编译器和运行时可能对我不知道的常见操作进行了优化。我应该将代码的运行时间与已经存在的时间进行比较

      static public string TrimAndLower(string str)
      {
      
          if (str == null)
          {
              return null;
          }
      
          int i = 0;
          int j = str.Length - 1;
          StringBuilder sb;
      
          while (i < str.Length)
          {
              if (Char.IsWhiteSpace(str[i])) // or say "if (str[i] == ' ')" if you only care about spaces
              {
                  i++;
              }
              else
              {
                  break;
              }
          }
      
          while (j > i)
          {
              if (Char.IsWhiteSpace(str[j])) // or say "if (str[j] == ' ')" if you only care about spaces
              {
                  j--;
              }
              else
              {
                  break;
              }
          }
      
          if (i > j)
          {
              return "";
          }
      
          sb = new StringBuilder(j - i + 1);
      
          while (i <= j)
          {
              // I was originally check for IsUpper before calling ToLower, probably not needed
              sb.Append(Char.ToLower(str[i]));
              i++;
          }
      
          return sb.ToString();
      }
      
      静态公共字符串TrimAndLower(字符串str)
      {
      如果(str==null)
      {
      返回null;
      }
      int i=0;
      int j=结构长度-1;
      为某人做准备;
      而(ii)
      {
      if(Char.IsWhiteSpace(str[j])//或者说“if(str[j]==”),如果你只关心空格的话
      {
      j--;
      }
      其他的
      {
      打破
      }
      }
      如果(i>j)
      {
      返回“”;
      }
      sb=新的StringBuilder(j-i+1);
      
      虽然(我可能
      Trim
      然后
      Lower
      会让它快一点;-)如果你真的需要每一个ms…读一下:他说用ToLower(referenceToACulture)而不是ToLower()@ David Heffernan,因为MiSoFt限制了我在C语言中的默认语言,因为我正在编写的应用程序的类型。它可以与SOM管理的C++混合,但是我必须把克里特岛单独的DLL。谢谢大家,你是信息!字符串操作已经被证明是更快的,在某些情况下比.C++ +克里斯看起来更快,在.NET中更快。一个被操纵的比较。我注意到你没有提供任何引用…..去掉一个额外的变量应该没有多大帮助。我们仍然在这里谈论创建2个
      string
      实例。这只是一个起点。我认为ghet没有意识到你可以链接方法。这不也会创建2个字符串吗?“你的字符串”。Trim()将返回一个字符串,然后ToLower();创建另一个字符串。这是相同的。这是唯一的方法,没有更快的方法。而且,使用char数组自己执行此操作将比CLR.ToLower()的本机方法慢虽然修剪会稍微快一点,但不会太慢afaik@ChrisS使用StringBuilder和使用状态机的单次迭代速度更快(就空间和时间复杂性而言),因为它避免了创建中间字符串),但您是对的,CLR的
      Trim
      ToLower
      方法“预优化”,这可能会导致更小字符串的更快结果。实际上:profile、profile和profile,以确定哪个应用程序更快。是的,谢谢提醒。顺便说一句,我还意识到一个简单的(非扩展)方法也可以。但我喜欢扩展方法。:)这个实现的一个特点是它只处理A-Z之间的字符。127以上的字符(如Ö)将不会转换为ö。而.NET String.ToLower将处理此类情况。这对提出问题的人来说可能很重要,也可能不重要。I“我很确定,如果Trim和ToLower不更改字符串,它们都会返回原始字符串,因此您的“优化”实际上会增加更多工作。对于任何对速度感兴趣的人,这篇博文
      static public string TrimAndLower(string str)
      {
      
          if (str == null)
          {
              return null;
          }
      
          int i = 0;
          int j = str.Length - 1;
          StringBuilder sb;
      
          while (i < str.Length)
          {
              if (Char.IsWhiteSpace(str[i])) // or say "if (str[i] == ' ')" if you only care about spaces
              {
                  i++;
              }
              else
              {
                  break;
              }
          }
      
          while (j > i)
          {
              if (Char.IsWhiteSpace(str[j])) // or say "if (str[j] == ' ')" if you only care about spaces
              {
                  j--;
              }
              else
              {
                  break;
              }
          }
      
          if (i > j)
          {
              return "";
          }
      
          sb = new StringBuilder(j - i + 1);
      
          while (i <= j)
          {
              // I was originally check for IsUpper before calling ToLower, probably not needed
              sb.Append(Char.ToLower(str[i]));
              i++;
          }
      
          return sb.ToString();
      }