スレッドセーフで、C#、Forループは、速試...同じループより速く回す。
質問
public Int64 ReturnDifferenceA()
{
User[] arrayList;
Int64 firstTicks;
IList<User> userList;
Int64 secondTicks;
System.Diagnostics.Stopwatch watch;
userList = Enumerable
.Range(0, 1000)
.Select(currentItem => new User()).ToList();
arrayList = userList.ToArray();
watch = new Stopwatch();
watch.Start();
for (Int32 loopCounter = 0; loopCounter < arrayList.Count(); loopCounter++)
{
DoThings(arrayList[loopCounter]);
}
watch.Stop();
firstTicks = watch.ElapsedTicks;
watch.Reset();
watch.Start();
for (Int32 loopCounter = 0; loopCounter < arrayList.Count(); loopCounter++)
{
DoThings(arrayList[loopCounter]);
}
watch.Stop();
secondTicks = watch.ElapsedTicks;
return firstTicks - secondTicks;
}
ご覧のとおりとかのリクとかその他もろもろは簡単です。リストを作成し、ユーザーの力では、"配列"を始め、ループのリストを通じて、メソッドの呼び出しを停止す。繰り返す。仕上げにより差からの最初の運行です。
現地に行って呼び出しこれらの:
differenceList = Enumerable
.Range(0, 50)
.Select(currentItem => ReturnDifferenceA()).ToList();
average = differenceList.Average();
differenceListA = Enumerable
.Range(0, 50)
.Select(currentItem => ReturnDifferenceA()).ToList();
averageA = differenceListA.Average();
differenceListB = Enumerable
.Range(0, 50)
.Select(currentItem => ReturnDifferenceA()).ToList();
averageB = differenceListB.Average();
現在は楽しい部分はすべての平均正により比較的大きな金額から、150kに300kダニ.
何が得られませんが私と同じリストで同じように、同じ方法などなどがあります。あのキャッシュ。
もう一つの興味深いことにすれば繰り返し処理を実行して、リスト前の初めての時計部門の平均値は約5kました。
解決
ところで、配列でIEnumerable.Count()を使用すると、Array.Lengthの何百倍も遅くなります...これは質問にはまったく答えませんが。
他のヒント
多くのキャッシングとパフォーマンスの最適化を行うランタイム環境を備えた高水準言語で実行していますが、これは一般的です。仮想マシンのウォームアップ、またはサーバーのウォームアップ(実稼働アプリケーションの場合)と呼ばれることもあります。
何かを繰り返し実行する場合、初回の測定ランタイムが大きくなるのに気づくでしょう。残りはより少ない量に横ばいになるはずです。
MATLABコードでこれを行います。ベンチマークループを初めて実行すると、5秒かかり、その後の時間は5分の1秒かかります。インタープリター言語は何らかの形のコンパイルを必要とするため、大きな違いですが、実際にはパフォーマンスに影響はありません。ほとんどの実稼働アプリケーションで「2回目」であるためです。
DoThings()は、最初に呼び出されるまでネイティブコードにJITコンパイルされない可能性があります。
.NETはJavaプラットフォームと同様にJIT環境であるためです。すべての高レベル.NETコードは、Microsoftの中間言語バイトコードにコンパイルされます。
プログラムを実行するには、このバイトコードをコンパイル/ネイティブマシンコードに変換する必要があります。ただし、コンパイルされた.NETプログラムファイルは、ネイティブマシンコードではなく、中間仮想マシンのバイトコードに保存されます。
最初の実行はJITコンパイルされているため、余分な時間がかかりました。 後続の実行はJITコンパイルする必要がなくなりましたが、ネイティブコードはJITキャッシュから取得されるため、高速になります。
その後の実行で終了せずにアプリケーションを維持しましたか?次に、2番目の理由もVMによるものです。 (VM:1 =仮想マシン、VM:2 =仮想メモリ)。現代のすべての一般化されたオペレーティングシステムは、実メモリのマップである仮想メモリ上でプロセスを実行し、オペレーティングシステムがシステムリソースの使用を管理および最適化できるようにします。使用頻度の低いプロセスは、他のプロセスがリソースを最適に使用できるように、頻繁にディスクキャッシュに流されます。
プロセスは最初は仮想メモリになかったため、メモリにスイープされるオーバーヘッドが発生する必要があります。その後、プロセスは最近使用された最上位リストの1つ(別名、最も最近使用されていないリストの下部)であったため、まだディスクキャッシュに一掃されていませんでした。
また、リソースは必要に応じてOSによってプロセスに割り当てられます。そのため、最初のラウンドでは、リソース境界を拡大するために、OSでエンベロープの競合をプッシュするという苦労をプロセスで行う必要がありました。
仮想マシンにより、.NETとJavaはほとんどのプログラミング機能をマシンに依存しないレイヤーに抽象化し、分離するため、マシンに依存するソフトウェアエンジニアが対処するための混乱が少なくなります。 Microsoft Windowsはかなり統一されたx86子孫ハードウェアで実行されますが、.NETプログラマーとユーザーに一貫したビューを提供するために、抽象化された仮想マシンを保証するために、OSバージョンとCPUモデルによって十分な違いがあります。
あなたは、3回それをやってもらえないと言います。2回目と3回目は比較的近いです。物事が遅いのはループを通るのは初めてだと思われます。
最初に実行するまで、呼び出す関数はJust-In-Timedではないと思われます。試すことができるのは、一度実行してから停止し、もう一度実行することです。コードを変更しなくても、前回の実行からのJust-In-Timeコンパイルは引き続き正常であり、表示される残りの最適化は、作業中の実際のキャッシュ効果です。
休暇とは別に、物質の温暖化のVMや機械のキャッシュ、JIT最適化を行うための瞬間:何か他のものはコンピュータはどうですか。他の3e42システム-サービスおよびタスクトレイthingies掴むものCPU?つく蒸気トを決めたアップデートの有無をチェック、IEとして何らかの手を打つ必要があfrightfully重要なのは、ウイルス対策プログラムものです。
試験はどの程度で分離でのすべてのその他のソフトウェア個セット。Offのソフトウェアできる限を測定した。
その後は何か?-つく測定方法で管理します。純(う)実行時のものが占める実行時の仮想サイクルの'.