【发布时间】:2014-02-21 17:00:38
【问题描述】:
我想知道是否有人可以向我解释编译器究竟会为我做些什么来观察一个简单方法的性能差异。
public static uint CalculateCheckSum(string str) {
char[] charArray = str.ToCharArray();
uint checkSum = 0;
foreach (char c in charArray) {
checkSum += c;
}
return checkSum % 256;
}
我正在与一位同事一起为消息处理应用程序进行一些基准测试/优化。在 Visual Studio 2012 中使用相同的输入字符串执行 1000 万次此函数的迭代大约需要 25 秒,但是当使用“优化代码”选项构建项目时,相同的代码在 7 秒内执行相同的 1000 万次迭代。
我非常有兴趣了解编译器在幕后做了什么,以便我们能够看到像这样看似无辜的代码块的性能提升超过 3 倍。
根据要求,这是一个完整的控制台应用程序,用于演示我所看到的内容。
class Program
{
public static uint CalculateCheckSum(string str)
{
char[] charArray = str.ToCharArray();
uint checkSum = 0;
foreach (char c in charArray)
{
checkSum += c;
}
return checkSum % 256;
}
static void Main(string[] args)
{
string stringToCount = "8=FIX.4.29=15135=D49=SFS56=TOMW34=11752=20101201-03:03:03.2321=DEMO=DG00121=155=IBM54=138=10040=160=20101201-03:03:03.23244=10.059=0100=ARCA10=246";
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
CalculateCheckSum(stringToCount);
}
stopwatch.Stop();
Console.WriteLine(stopwatch.Elapsed);
}
}
在调试中运行优化关闭我看到 13 秒,我得到 2 秒。
在 Release 中运行,优化关闭 3.1 秒,开启 2.3 秒。
【问题讨论】:
-
几个问题;你在
Release模式下运行吗?您是否使用Stopwatch进行计时? -
冒险猜测它可能会将
foreach循环变成for循环,这将防止它不得不从数组切换到枚举。有关这方面的一些讨论,请参阅 stackoverflow.com/questions/365615/…。 -
坐下来等待 Eric Lippert 提供明确的、无需猜测的答复。
-
@JesseCarter:我强烈建议您独立运行它(例如作为控制台应用程序),而不是从单元测试运行器中运行。删除尽可能多的无关位。
-
您也可以发布您的输入字符串吗?或者更理想的是,一个简短但完整的程序可以展示差异。
标签: c# visual-studio compiler-construction