.NETチューニングレコード - 転送区風の伝説

同じプロセスを実行し、パフォーマンステストを行う際に、新しいプロジェクトの会社とは奇妙な問題を発見した48コア(HP580 G7のPCサーバ)サーバ120秒、4コアのPC内に取りボードに限り、90秒として、この質問で、同社はこの問題を解決するには、Microsoftのエンジニアを雇いました。

一日を過ごした後は、デバッグと最適化をトレースし、時間のかかる70秒に、プロセスは、いくつかの最適化の.NETオブジェクトを含み、実際の効果は明ら​​かです。この記事では、段階的なノートの結論であるだけでなく、非常に有益。

 

、DataView.ToTableパフォーマンスの問題()の後に

エンジニアはこの方法に対処するための時間は、トラッキングコードで非常に遅い見つけ、コードの全体ロジック時間のほとんどを占めています。この方法では、効果は明ら​​かである最適化されています。

MSDNを確認し、関係者は、パフォーマンス上のDataView.ToTable()メソッドのヒントを与えていないが、あなたはMSDNを見てみたい、この方法では、発見した外国人は3通りの方法でこれを実行するには、以下のコードに戻ってきた2006年でこの方法は、効率性に大きな違いを発見しました。MSDN:DataView.ToTable () )。

私たちは本当に問題を再現することができ、新しいプロジェクトを作成し、コードをコピーしました。次のように全体のプロセスは、おそらく次のとおりです。

背景は、データワードが、このデータテーブルデータビューに転送される50万データテーブルデータ、があり、その後Totableによってこのデータビューから()メソッドは、データを別のデータテーブル同じアーキテクチャに転送されます。

ターゲットデータテーブルオブジェクトを作成するための最初の方法は、直接()メソッドはtoTableによって変換します。プロセスは取っ:27.0504秒。

第二の目標DATATABLE方法を作成した後、それは主キーを設定します。データは、次のコードによって、ターゲットテーブルに加えました。

                 foreachの(ds.TablesでのDataRow DR [0] .Rows)

                {

                    DataRow [] drrepetido = dsRes.Tables [0] .Select( "勇気=" + DR [ "勇気"])。

                    もし(drrepetido.Length == 0)

                        dsRes.Tables [0] .ImportRow(DR)。

                }

プロセスは取っ:11.7624秒。

 

第3の実施形態は、元のターゲットデータテーブルアーキテクチャ、データテーブルオブジェクトの新しいインスタンスを作成し、対応する列を追加し、次のように、ハッシュ表、ターゲット表書き込みサイクルを作成できません。

                DataTable dtを=新しいのDataTable();

                dt.Columns.Add( "勇気"、ds.Tables [0] .Columns [ "勇気"]データ型。)

                HashtableのHT =新しいHashtableの();

                foreachの(ds.TablesでのDataRow DR [0] .Rows)

                {

                    (もし!ht.ContainsKey(DR [0]))

                    {

                        ht.Add(DR [0]、NULL);

                        DataRow newRow = dt.NewRow()。

                        newRow [0] = DR [0]。

                        dt.Rows.Add(newRow)。

                    }

                }

プロセスがかかった:0.2184秒。

 

三つの方法のコントラストは、非常に怖いました。しかし、Microsoftは、与えられた理由がないように思われます。

 

二、StringBuilderの()パフォーマンスの問題は、ファイルによって引き起こされていません

 

StringBuilderのも多くの記事を読む程度前にした後、問題の開発者プログラムと前回同様に、GCのStringBuilderオブジェクトが処理され続ける)(ループ本体続けるにappandで、その結果、より多くの推奨インスタンス化する長さの値を設定していません。これは多くの時間を消費します。

それのよりのStringBuilder()オブジェクト、またはいくつかの単語について、その後。デフォルト値は16容量維持です。

StringBuilderのコストが大きなオブジェクトを作成するので、文字列連結少ないターゲットの場合には、過度の虐待は、無駄のStringBuilderのパフォーマンスではなく、節約になることができます。だけのStringBuilderに検討する前に、予測不可能な数値や文字列操作の多くは、実現しています。文字列型「+」作動接続、実際にオーバーロード演算子「+」はString.Concatが操作呼び出し、コンパイラは、コンパイラ渡される引数の数に応じて、そのような接続処理の動作を最適化します時間割り当ては、メモリに対応し、順次コピーに対応する文字列。使用中のStringBuilder起因デフォルトのメモリ割り当て、頻繁操作の容量不足に別段の指定が最適な容量値は、不適切な実装です。通常の状況下では、単純な文字列の連結、および接続文字列を完了するために、好みString.Concat String.Join他の操作で使用する必要がありますが、String.Concatボクシングの動作を監視することが可能となります。

 

第三に、パフォーマンスの問題を持って来るために私を可能にします

StringBuilder.toStringは()。トリム場合()かどうかがStringBuilderの値を決定するために、それは()の代わりにStringBuilder.Lenthであってもよいです。

おすすめ

転載: www.cnblogs.com/mlwork/p/11752745.html