2011-09-25 84 views
7

我正在使用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); 
     } 
    } 
} 

我坐了几个小时,无法弄清楚这里发生了什么。 你有什么想法吗?

+0

System.String类本身运行在.NET 4改为用大量的工作,对在CLR的NLS位。你不能合理地期待类似的结果,只有希望。 –

回答

15

这听起来像你刚发现的情况是,.NET 4是快了很多。默认情况下,您的应用程序正在运行它构建的目标框架。当你使用.NET 4时,它会更快。这可能是一个JIT编译器的改进,它可能会碰到你的情况,或者它可能是一个框架改进 - 但在新版本中某些事情会更快,这应该不会让人感到意外。

(对于它的价值,我会增加,如果我是你,在.NET 4你在时间上......我的盒子迭代次数,每次迭代只有10毫秒,这是不是一个真正的。伟大的测量我宁愿基准至少几秒钟)

(而像米奇,我可以证实,我看到相同效果)

编辑:。我刚刚调查了此位进一步,并看到一个有趣的效果......我假设我们打电话haystack.IndexOf(needle, StringComparison.OrdinalIgnoreCase)

  • 在.NET上2,结果是大致一样的,但是大的“针”是
  • 在.NET 4:
    • 如果needlehaystack大(根据你的例子).NET 4比2的.NET
    • 快得多
    • 如果needle的尺寸与haystack相同,.NET 4比.NET慢位2
    • 如果needlehaystack小,.NET 4是很多比.NET慢2

(这是保持一个测试,其中的needle第一个字符不会出现在haystack,顺便说一句。)

+0

不应该“当你强迫它使用.NET”阅读“当你强迫它使用.NET ** 4 **”? – Ani

+0

@Ani:哎呀,是的,谢谢。 –

+4

“如果针比干草堆小,.NET 4会慢很多” - 看起来像是一个非常糟糕的优化。 –

4

我只是跑的基准稍做调整(其中包括更多的迭代和平均),和可以确认.NET 4.0目标版本的速度确实快了4-5倍。

所以大概IndexOf()在.NET 4进行了优化。0

3

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

+0

哇 - 这真的很奇怪 - 不知道CLR/BCL的一些内部人员是否可以对此进行说明... – Carsten

+0

甚至在短草垛中寻找长针头还有什么意义?这不是由设计造成的吗? – yas4891

+0

@ yas4891:是的,但这是原来的问题,它的表现非常不同。 –