2011-09-25 82 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:是的,但這是原來的問題,它的表現非常不同。 –