一个更快的方法来反转一个字符串?

Cod*_*per 3 c# pointers

下面是我可以创建的用于反转String的最快代码

public static void ReverseFast(string x)
{
    string text = x;
    StringBuilder reverse = new StringBuilder();

    for (int i = text.Length - 1; i >= 0; i--)
    {
        reverse.Append(text[i]);
    }
      Console.WriteLine(reverse);
}
Run Code Online (Sandbox Code Playgroud)

我想解决这个等式中的每个瓶颈,使其尽可能快.到目前为止我唯一能找到的是阵列边界检查,我只是部分理解.无论如何,如果您使用.Length编译器决定不检查边界但是如果您正在递减,因为我理解它是否仍然禁用for它,它仍然进行边界检查?有人可以将此转换为使用指针,这将避免边界检查,我想测试100k +字符范围内的字符串的速度差异.

根据下面的评论和帖子,这是我到目前为止所提出的.

public static void ReverseFast(string x)
{
    StringBuilder reverse = new StringBuilder(x.Length);
    for (int i = x.Length - 1; i >= 0; i--)
    {
        reverse.Append(x[i]);
    }
    Console.WriteLine(reverse);
}
Run Code Online (Sandbox Code Playgroud)

上述解决方案比建议的重复问题答案快得多.这个问题实际上是在5000*26个字符+范围内解决逆转问题.我仍然希望使用指针来测试它,以确定是否没有瓶颈,尤其是如此大量的字符.

Mar*_*ell 13

var arr = x.ToCharArray();
Array.Reverse(arr);
return new string(arr);
Run Code Online (Sandbox Code Playgroud)

但请注意,这将反转任何unicode修饰符(重音符号等).

基准测试:

Array.Reverse: 179ms
StringBuilder: 475ms
Run Code Online (Sandbox Code Playgroud)

附:

static void Main()
{
    string text = new string('x', 100000);
    GC.Collect();
    GC.WaitForPendingFinalizers();
    var watch = Stopwatch.StartNew();
    const int LOOP = 1000;
    for (int i = 0; i < LOOP; i++)
    {
        var arr = text.ToCharArray();
        Array.Reverse(arr);
        string y = new string(arr);
    }
    watch.Stop();
    Console.WriteLine("Array.Reverse: {0}ms", watch.ElapsedMilliseconds);

    GC.Collect();
    GC.WaitForPendingFinalizers();
    watch = Stopwatch.StartNew();
    for (int i = 0; i < LOOP; i++)
    {
        var reverse = new StringBuilder(text.Length);
        for (int j = text.Length - 1; j >= 0; j--)
        {
            reverse.Append(text[j]);
        }
        string y = reverse.ToString();
    }
    watch.Stop();
    Console.WriteLine("StringBuilder: {0}ms", watch.ElapsedMilliseconds);
}
Run Code Online (Sandbox Code Playgroud)

如果我们尝试一个长度为500的字符串并循环500000次:

Array.Reverse: 480ms
StringBuilder: 1176ms
Run Code Online (Sandbox Code Playgroud)

我也试过加入unsafe那个,即

fixed (char* c = text)
{
    for (int j = text.Length - 1; j >= 0; j--)
    {
        reverse.Append(c[j]);
    }
}
Run Code Online (Sandbox Code Playgroud)

这没有任何区别.

我也加入了JeffRSon的回答; 我明白了:

Array.Reverse: 459ms
StringBuilder: 1092ms
Pointer: 513ms
Run Code Online (Sandbox Code Playgroud)

(对于500长度×5000次迭代测试)

  • 对不起,我认为这个问题是"一个快速反转字符串的方法?" 我们通常不会告诉人们进行基准测试吗?;) (3认同)