2017-08-04 87 views
0

我在我的應用程序上運行了一些性能分析,發現檢查控制檯輸出編碼需要將近兩倍的時間來檢查我的應用程序是否運行完整的性能迭代。爲什麼檢查Console.OutputEncoding需要很長時間?

我通過檢查:

Console.OutputEncoding.EncodingName != Encoding.UTF8.EncodingName 

這個檢查需要80〜蜱(8000納秒),我(生成控制檯表)整個應用程序只需要50〜蜱(5000納秒),而不該運行,並經歷了數百個條件。

爲什麼檢查輸出編碼需要很多時間?我可以加快速度嗎?

+0

我不知道你是否可以將這個false等於一個linq表達式。你可以添加一些你的表達式檢查的更多上下文嗎? –

+1

@BenderBending它只是檢查編碼。如果控制檯編碼不等於UTF8,那麼我將它設置爲UTF8。因爲我會添加一個間接級別,所以LINQ可能會變慢。 –

+0

投票過關的用戶是否可以解釋爲什麼您認爲這太寬?範圍似乎對我來說非常明確。 –

回答

1

如果我不得不冒險猜測這是因爲你正在比較EncodingName,這會導致潛在的昂貴查找(以及後續的字符串比較)。是否有理由不直接比較編碼?

!Console.OutputEncoding.Equals(Encoding.UTF8) 

本地測試它看起來快得多。

+0

這需要大約相同的時間,有趣的是,雖然用這種方式,它每次支票從65-100滴答跳轉。 'EncodingName'檢查一直掛起80 + = 2個滴答。 –

+0

@DouglasGaskell我不能在本地重現。對我來說,直接比較比'EncodingName'屬性快得多。你怎麼分析這個? – Kyle

+0

良好的通話,我的測試是有缺陷的,我無意中將'EncodingName'位留在'Encoding.UTF8'上。我正在使用秒錶來記錄經過的滴答。在發佈版本中,需要3個刻度,而名稱檢查需要38個刻度。 –

2

OutputEncoding,吸氣參考來源:https://referencesource.microsoft.com/#mscorlib/system/console.cs,594

public static Encoding OutputEncoding { 
    [System.Security.SecuritySafeCritical] // auto-generated 
    get { 

     Contract.Ensures(Contract.Result<Encoding>() != null); 

     if (null != _outputEncoding) 
      return _outputEncoding; 

     lock(InternalSyncObject) { 

      if (null != _outputEncoding) 
       return _outputEncoding; 

      uint cp = Win32Native.GetConsoleOutputCP(); 
      _outputEncoding = Encoding.GetEncoding((int) cp); 
      return _outputEncoding; 
     } 
    } 
    ... 

我注意到的第一件事是,它採取了鎖,所以有一點開銷已經存在。它也似乎被延遲實例化:第一次獲得OutputEncoding時,它需要先執行PInvoke,然後再執行Encoding.GetEncoding(如果您看到,這不是一項簡單的任務)。但是所有後續調用都會避免鎖定並返回已經實例化的值。所以,如果你多次獲得它,成本將被分攤到幾乎沒有任何東西。

如果你只是得到它一次......你真的需要優化的東西只需要8微秒?

+0

我得到它多次,我只在第一次測量後,以防止延遲加載。至於優化,我的圖書館是考慮到重度優化而構建的。通常我會說8微秒並不重要,但是當這是我的庫實例化的兩倍時間,收集數據,格式和輸出時,我想優化它。 –

+0

看過之後,除非我模擬'uint cp = Win32Native.GetConsoleOutputCP();'調用,否則它看起來並沒有任何解決方法,但我想可以在框架版本之間進行更改,因爲它是內部版本。 –

相關問題