2017-08-04 7 views
0

私はアプリケーションでいくつかのパフォーマンスプロファイリングを実行しています。コンソール出力のエンコーディングをチェックするのは、アプリケーションが完全なパフォーマンスの繰り返しを実行するのに約2倍の時間がかかります。Console.OutputEncodingのチェックに時間がかかるのはなぜですか?

は私が経由してチェックしています:

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

このチェックはこれなしで実行するために〜80ティック(8000 NS)、(コンソールテーブルを生成する)私の全体のアプリケーションのみをとる〜50ティック(5000 NS)を取り、数百の条件を通過します。

なぜ出力エンコードのチェックに時間がかかるのですか?これをスピードアップできますか? OutputEncodingのゲッターのための

+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

いいえ、私のテストには欠陥があり、誤って 'Encoding.UTF8'に' .EncodingName'ビットを残しました。私は経過時間を記録するためにストップウォッチを使用しています。リリースビルドでは、これは3ティック、名前チェックと38ティックが必要です。 –

2

リファレンスソース: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(これはわかりますが、簡単な作業ではありません)が必要です。しかし、その後のすべての呼び出しはロックを回避し、既にインスタンス化された値を返します。だから、何度もそれを取得しているならば、コストはほとんど何も償却されません。

1回だけ取得している場合... 本当には、わずか8マイクロ秒かかるものを最適化する必要がありますか?

+0

私はそれを何度も得る、私は怠惰なロードをした場合に初めて初めて測定する。最適化については、私のライブラリは重い最適化を念頭に置いて構築されています。通常は8マイクロ秒は問題ではありませんが、ライブラリがインスタンス化してデータ、フォーマット、出力を収集するのに2倍の時間がかかる場合は、最適化したいと考えています。 –

+0

'uint cp = Win32Native.GetConsoleOutputCP();'の呼び出しをシミュレートしない限り、周囲を見渡したように見えませんが、フレームワークのバージョン間で変更できると思います。 –

関連する問題