gpt4 book ai didi

c# - 编译器使用经典交换对我的字符串反向方法进行了哪些优化?

转载 作者:太空狗 更新时间:2023-10-30 00:48:17 26 4
gpt4 key购买 nike

问题背景

我读了this关于如何尽快反转字符串的问题。我发现答案之一是比较不同的方法。在其中一个中,他们只是运行一个循环,将位置 i 的元素与位置 string.Length-1-i 的元素交换,但他们通过 XOR 使用已知的棘手交换.我想知道与通过时间变量使用经典交换的相同方法相比,通过 XOR 使用交换来反转字符串的速度有多快。令人惊讶的是,与 XOR 相比,我的性能提高了近 50%。

问题

编译器是否在幕后做了一些神奇的事情,为什么我会得到这个结果?

使用基准修改后的代码

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ContestLibrary
{
public class Problem
{
delegate string StringDelegate(string s);

static void Benchmark(string description, StringDelegate d, int times, string text)
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int j = 0; j < times; j++)
{
d(text);
}
sw.Stop();
Console.WriteLine("{0} Ticks {1} : called {2} times.", sw.ElapsedTicks, description, times);
}

public static string ReverseXor(string s)
{
char[] charArray = s.ToCharArray();
int len = s.Length - 1;

for (int i = 0; i < len; i++, len--)
{
charArray[i] ^= charArray[len];
charArray[len] ^= charArray[i];
charArray[i] ^= charArray[len];
}

return new string(charArray);
}

public static string ReverseClassic(string s)
{
char[] charArray = s.ToCharArray();
int len = s.Length-1;

for (int i = 0; i < len; i++, len--)
{
char temp = charArray[len];
charArray[len] = charArray[i];
charArray[i] = temp;
}
return new string(charArray);
}

public static string StringOfLength(int length)
{
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++)
{
sb.Append(Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))));
}
return sb.ToString();
}

static void Main(string[] args)
{

int[] lengths = new int[] {1,10,100,1000, 10000, 100000};

foreach (int l in lengths)
{
int iterations = 10000;
string text = StringOfLength(l);
Benchmark(String.Format("Classic (Length: {0})", l), ReverseClassic, iterations, text);
Benchmark(String.Format("Xor (Length: {0})", l), ReverseXor, iterations, text);
Console.WriteLine();
}
Console.Read();
}
}
}

最佳答案

原因很简单,让我们看看每个函数在 IL 代码中有多少操作。但首先,让我们看看这两个函数在时间上的真正差异。你说 XOR 函数比另一个慢了近 50%,当我在 Debug模式下运行代码时我得到了那个结果,但是你必须在 Release模式下运行代码才能完全允许优化器完成它的工作:)。在 Release模式下,XOR 函数几乎慢了 3 倍。

图片具有 for 循环内部分的 IL 代码,这是唯一发生变化的部分。

第一张图是带有temp变量的函数

Classic code with the temp variable

第二张图是异或函数

XOR function

如您所见,指令数量的差异很大,14 对 34。3 倍的时间差异来自一些操作,例如 conv.u2,它们有点昂贵。

关于c# - 编译器使用经典交换对我的字符串反向方法进行了哪些优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48180486/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com