奇怪的性能行为
我正在使用Visual Studio 2010 SP1,目标框架为2.0,平台目标:任何CPU,在Windows 7 x64 SP1下测试。奇怪的性能行为
我遇到奇怪的表现行为。
没有一个app.config,或者与下面的app.config,它使我的程序运行速度很慢(秒表显示〜0.11 S)
<?xml version="1.0"?>
<configuration>
<startup >
<supportedRuntime version="v2.0.50727" />
</startup>
</configuration>
下的app.config让我的程序运行X5倍的速度(秒表示出〜0.02秒)
<?xml version="1.0"?>
<configuration>
<startup >
<supportedRuntime version="v4.0.30319" sku=".NETFramework,Version=v4.0" />
</startup>
</configuration>
这是测试的程序代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
class Program
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
while (true)
{
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000; i++)
{
"blablabla".IndexOf("ngrhotbegmhroes", StringComparison.OrdinalIgnoreCase);
}
Console.WriteLine(sw.Elapsed);
}
}
}
我坐了几个小时,无法弄清楚这里发生了什么。 你有什么想法吗?
这听起来像你刚发现的情况是,.NET 4是快了很多。默认情况下,您的应用程序正在运行它构建的目标框架。当你使用.NET 4时,它会更快。这可能是一个JIT编译器的改进,它可能会碰到你的情况,或者它可能是一个框架改进 - 但在新版本中某些事情会更快,这应该不会让人感到意外。
(对于它的价值,我会增加,如果我是你,在.NET 4你在时间上......我的盒子迭代次数,每次迭代只有10毫秒,这是不是一个真正的。伟大的测量我宁愿基准至少几秒钟)
(而像米奇,我可以证实,我看到相同效果)
编辑:。我刚刚调查了此位进一步,并看到一个有趣的效果......我假设我们打电话haystack.IndexOf(needle, StringComparison.OrdinalIgnoreCase)
:
- 在.NET上2,结果是大致一样的,但是大的“针”是
- 在.NET 4:
- 如果
needle
比haystack
大(根据你的例子).NET 4比2的.NET 快得多
- 如果
needle
的尺寸与haystack
相同,.NET 4比.NET慢小位2 - 如果
needle
比haystack
小,.NET 4是很多比.NET慢2
- 如果
(这是保持一个测试,其中的needle
第一个字符不会出现在haystack
,顺便说一句。)
不应该“当你强迫它使用.NET”阅读“当你强迫它使用.NET ** 4 **”? – Ani
@Ani:哎呀,是的,谢谢。 –
“如果针比干草堆小,.NET 4会慢很多” - 看起来像是一个非常糟糕的优化。 –
我只是跑的基准稍做调整(其中包括更多的迭代和平均),和可以确认.NET 4.0目标版本的速度确实快了4-5倍。
所以大概IndexOf()
在.NET 4进行了优化。0
OK,一些基准与新VS11
n = 1000000;
string haystack = "ngrhotbegmhroes";
string needle = "blablablablablablablablablangrhotbegmhrobla bla";
.NET 4.5 : 8 ms
.NET 4.0 : 8 ms
.NET 3.5 : 45 ms
.NET 2.0 : 45 ms
因此,这些初步结果确认你的发现,新版本的速度更快。
然而更为常见的寻找是个较大的字符串中短字符串:
n = 1000000;
haystack = "blablablablablablablablablangrhotbegmhrobla bla";
needle = "ngrhotbegmhroes";
.NET 4.5 : 1020 ms
.NET 4.0 : 1020 ms
.NET 3.5 : 155 ms
.NET 2.0 : 155 ms
而且具有更长的干草堆(〜400个字符)
.NET 4.0 : 12100 ms
.NET 2.0 : 1700 ms
这意味着事情就对于最常见的使用模式更糟糕......
在Release配置所有测量和Cl可用的配置文件。
来自VS 11,按Ctrl + F5
运7H,酷睿i7 2620M
System.String类本身运行在.NET 4改为用大量的工作,对在CLR的NLS位。你不能合理地期待类似的结果,只有希望。 –