2009-09-29 66 views
5

我有一種情況,我的正則表達式在Windows Server 2008上編譯得非常慢。我編寫了一個小型控制檯應用程序來突出顯示此問題。該應用程序生成自己的輸入,並從XML文件中的單詞構建正則表達式。我構建了此應用的發佈版本,並在我的個人筆記本電腦(運行XP)和Windows 2008服務器上運行。正則表達式花了0.21秒在我的筆記本電腦上編譯,但在服務器上編譯了23秒。Windows Server 2008上的正則表達式緩慢

任何想法可能導致這種情況?這個問題只是第一次使用正則表達式(當它是第一次編譯 - 此後它很好)

我還發現了另一個問題 - 當在同一Windows 2008服務器上的正則表達式中使用\s+時,內存氣球(使用4GB +),正則表達式的編譯永遠不會結束。

是否有正則表達式和64位.net的已知問題?是否有修復/補丁可用於此?我無法在網上找到任何信息,但我在Framework 2.0中發現了一些關於這個相同問題的文章 - 當然這已經被修復了嗎?

更多信息: 服務器運行64位版本的.net框架(3.5 SP1),並在我的筆記本電腦上安裝了Visual Studio 2008和3.5框架。正則表達式是如下形式的:^word$|^word$|^word$和被構造有以下標誌:RegexOptions.IgnoreCase | RegexOptions.Compiled


這裏是一個代碼段:

StringBuilder regexString = new StringBuilder(); 
if (!String.IsNullOrEmpty(fileLocation)) 
{ 
    XmlTextReader textReader = new XmlTextReader(fileLocation); 
    textReader.Read(); 
    while (textReader.Read()) 
    { 
     textReader.MoveToElement(); 
     if (textReader.Name == "word") 
     { 
      regexString.Append("^" + textReader.GetAttribute(0) + "$|"); 
     } 
    } 
    ProfanityFilter = new Regex(regexString.ToString(0, regexString.Length - 1), RegexOptions.IgnoreCase | RegexOptions.Compiled); 
} 

DateTime time = DateTime.Now; 
Console.WriteLine("\nIsProfane:\n" + ProfanityFilter.IsMatch("test")); 
Console.WriteLine("\nTime: " + (DateTime.Now - time).TotalSeconds); 
Console.ReadKey(); 

這導致爲0.21秒的時間在我的筆記本在2008年服務器上爲23秒。 XML文件包含168個字的格式如下:

<word text="test" /> 
+3

代碼示例如何處理正則表達式和xml? – 2009-09-29 12:47:25

回答

4

我找到了一個解決方案,給出不正確的,但在我的情況下完美。由於某種原因,如果我忽略了RegexOptions.Compiled標誌,Regex要快得多。我甚至設法在2008服務器上以不到65毫秒的100個長短語執行Regex

這必須是.net庫中的一個錯誤,因爲未編譯版本應該比編譯版本慢得多。無論哪種方式,每次檢查1毫秒以下對我來說是非常可以接受的:)

+0

您可能還想嘗試更多替代正則表達式模式以找到最佳模式,例如/ ^(word | word | word | word)$ /而不是/^word $ |^word $ |^word $ /。 – brianary 2009-09-30 15:38:29

+0

是的,我知道這一點。就像我在原始問題中提到的那樣,我只是爲了突出問題而編寫了一個控制檯應用程序。這個完全相同的正則表達式在我的筆記本電腦上以0.21秒編譯,所以它不需要在64位服務器上編譯23秒。 – pjmyburg 2009-10-01 06:31:37

+0

有相同的問題和解決方案,它設置爲編譯它在我的本地XP框上運行良好,當上傳到服務器每個正則表達式需要40+秒。刪除編譯選項和8個調用現在總共不到1秒。 – ManiacZX 2010-08-04 20:03:13

4

使用Regex.CompileToAssembly方法您可以預先編譯正則表達式,然後你可以部署編譯後的正則表達式到您的服務器。

+0

是的,但這意味着服務的非技術管理員不能僅僅向XML文件添加一個單詞 - 每次都需要重新編譯DLL。好的建議,但。 – pjmyburg 2009-09-30 15:24:05

+1

我認爲他的意思是說,在讀入文件之後,您可以使用RegexOptions.Compiled選項來優化正則表達式的執行。 – brianary 2009-09-30 15:35:09

+0

不,他的意思是預先將正則表達式編譯爲DLL文件(彙編) - 這就是CompileToAssembly方法的作用。 RegexOptions.Compiled標誌是整個問題的原因。這確實是我想要去的方式,但似乎在64位.net庫中存在一個錯誤。 – pjmyburg 2009-10-01 06:29:45

1

我遇到了完全相同的問題。我的應用在x86機器上工作正常,但內存氣球並掛在x64上。刪除編譯標誌沒有幫助。我今天在.net 4.0上試過了,問題依然存在。如果你有repro,我建議你提交一個bug。

我認爲MSFT知道這一點,看到底部comment here

但讓他們決定,如果這是同樣的錯誤。如果您提交了文件,請在此處添加鏈接,以便我可以添加我的評論。

+0

我遇到了在Windows Server 2008 R2 64位機器上運行的.NET 4.0應用程序的相同問題。 關於這個問題的任何消息? Doron – DoronBM 2012-03-06 18:44:32

+0

@DoronBM,請評論上面的Microsoft錯誤數據庫鏈接,並與您的Microsoft代表一起努力升級它。謝謝!據我所知,沒有解決辦法。 – Barka 2012-03-07 18:56:13