したがって、このスレッドはすべてトークであり、数字はありません。メトリックをトークしましょう。Visual Studio 2010を使用してパフォーマンスメトリックを取得するために、いくつかのテストコードを実行しました。
これらのメトリックは、デバッグモードとリリースモード(最適化されていない状態と最適化された状態)でそれぞれ1,000万回の反復を行った10回のテスト実行でのいずれかの方法の平均時間を計算することで得られました。
(デバッグ)キャスト方法:〜32ミリ秒割り当て方法:〜26ミリ秒
(リリース)キャスト方法:〜20ms割り当て方法:〜22ms
また興味深いのは、これらのメトリックを、gcnewのみを使用するマネージC ++の同様のコードと比較することであり、結果は大きく異なります。
もう一度同じ設定。キャスト方法の比較を除いて: "IntPtr ^ ptr =(IntPtr)i;" vs割り当て方法: "IntPtr ^ ptr =(IntPtr)i;"。
(デバッグ)キャスト方法:〜91ms割り当て方法:〜127ms
(リリース)キャスティング方法:〜22ms割り当て方法:〜124ms
さて、頭を悩ませているのなら、なぜC#はマネージC ++よりもはるかに高速なのか、答えはそうではないということです。IntPtrを使用する最も効率的な方法は、値型への参照ではなく、値型として使用することです。たとえば、「IntPtr ptr =(IntPtr)i;」のようになります。これにより、〜24ms(さらにデバッグ)または(〜22リリースモード)が得られます。90msではなく22msを取得するために、コンパイラによって上記でどのように最適化されたかを確認してください。
C#での結論は、本当に本当にタイトなコードを見ているのでなければ、それは問題ではありません。リリースの私のコードでは、キャストをコメントアウトすると同じ〜22msが得られたため、実際にはキャストをすぐに最適化していたと思います。しかし、ほとんどの場合、コンパイラーはC#でこれに背を向けていますが、少なくともVS2010にはあります。ただし、マネージC ++ / CLIでは、パフォーマンスの制約が最小限でさえあるコードを検討している場合は、注意が必要です。コンパイラはキャストアプローチへのgcnew割り当てを自動的に最適化せず、ほぼ6倍高速です...実際にC ++ / CLIでこの特定の問題に遭遇したため、リアルタイムオーディオを処理するときにこのスレッドに投稿することになりました。処理。私のコード(C#):(私のマネージC ++コードは、自分でAverage()を記述し、メッセージボックスではなくコンソールを使用して出力する必要があることを除いて、非常に似ていました)。
static void Main()
{
List<int> castTimings = new List<int>();
List<int> allocTimings = new List<int>();
for (int i = 0; i < TEST_RUNS; ++i)
{
castTimings.Add(RunCastMethod().Milliseconds);
allocTimings.Add(RunAllocationMethod().Milliseconds);
}
MessageBox.Show(string.Format("Casting Method took: {0}ms", castTimings.Average() ));
MessageBox.Show(string.Format("Allocation Method took: {0}ms", allocTimings.Average() ));
}
private static TimeSpan RunAllocationMethod() {
DateTime start = DateTime.Now;
for (int i = 0; i < TEST_ITERATIONS; ++i)
{
IntPtr ptr = new IntPtr(i);
}
return ( DateTime.Now - start );
}
private static TimeSpan RunCastMethod()
{
DateTime start = DateTime.Now;
for (int i = 0; i < TEST_ITERATIONS; ++i)
{
IntPtr ptr = (IntPtr) i;
}
return (DateTime.Now - start);
}