我假设数百万个带有或不带有尾随空格的字符串。我想计算每个字符串中尾随空格的数量。
我正在为每个字符串执行此操作。
int count = input.Length - input.TrimEnd().Length;
但我认为这是低效的,因为我通过TrimEnd()为每个字符串使用方法来创建不必要的字符串。
我曾想过使用另一种方法来计算尾随空格,方法是反向遍历每个字符的字符串并检查直到第一个非空格字符(将计数增加 1)。
有没有更快更有效的方法来做到这一点?字符串很小,但有数百万。
我假设数百万个带有或不带有尾随空格的字符串。我想计算每个字符串中尾随空格的数量。
我正在为每个字符串执行此操作。
int count = input.Length - input.TrimEnd().Length;
但我认为这是低效的,因为我通过TrimEnd()为每个字符串使用方法来创建不必要的字符串。
我曾想过使用另一种方法来计算尾随空格,方法是反向遍历每个字符的字符串并检查直到第一个非空格字符(将计数增加 1)。
有没有更快更有效的方法来做到这一点?字符串很小,但有数百万。
编辑:我没有进行分析,并将其纳入扩展方法:
void Main()
{
string test = "StackOverflow ";
int count = test.WhiteSpaceAtEnd();
}
public static class StringExtensions
{
public static int WhiteSpaceAtEnd(this string self)
{
int count = 0;
int ix = self.Length - 1;
while (ix >= 0 && char.IsWhiteSpace(self[ix--]))
++count;
return count;
}
}
这里有 2 种可能的解决方案,一种使用for循环,另一种使用 Linq。这些都是扩展方法的形式。
public static class StringExtensions {
public static int CountTrailingSpaces(this string s) {
int count = 0;
for (int i = s.Length- 1; i >= 0; i--) {
if (Char.IsWhiteSpace(s[i])) {
count++;
}
else {
return count;
}
}
return count;
}
public static int CountTrailingSpacesLinq(this string s) {
return s.Reverse().TakeWhile(Char.IsWhiteSpace).Count();
}
}
然后您可以按如下方式调用它们:
static void Main(string[] args) {
string s = "test ";
Console.WriteLine(s.CountTrailingSpaces());
Console.WriteLine(s.CountTrailingSpacesLinq());
}
我使用此测试代码收到的输出是:
2
2
添加一些快速的性能指标。我强烈建议使用CountTrailingSpaces. 如下所示,这明显更快。
for使用循环对字符串执行 1,000,000 次操作的总滴答数与linq方法明显不同。
对于:803529 滴答
Linq: 7171201 滴答
性能测试代码如下所示:
class Program {
private static Random Random;
private static Stopwatch Stopwatch;
static void Main(string[] args) {
Random = new Random(Guid.NewGuid().GetHashCode());
Stopwatch = new Stopwatch();
decimal forLoop = 0;
decimal linq = 0;
for (int i = 0; i < 1000000; i++) {
string s = RandomString(100);
Stopwatch.Restart();
s.CountTrailingSpaces();
Stopwatch.Stop();
forLoop += Stopwatch.ElapsedTicks;
Stopwatch.Restart();
s.CountTrailingSpacesLinq();
Stopwatch.Stop();
linq += Stopwatch.ElapsedTicks;
}
Console.WriteLine($"For:\t{forLoop}");
Console.WriteLine($"Linq:\t{linq}");
}
private static string RandomString(int length) {
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ";
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[Random.Next(s.Length)]).ToArray());
}
}
public static class StringExtensions {
public static int CountTrailingSpaces(this string s) {
int count = 0;
for (int i = s.Length - 1; i >= 0; i--) {
if (Char.IsWhiteSpace(s[i])) {
count++;
}
else {
return count;
}
}
return count;
}
public static int CountTrailingSpacesLinq(this string s) {
return s.Reverse().TakeWhile(Char.IsWhiteSpace).Count();
}
}