私のチームは、大規模なシミュレーション アプリケーションの COM API を扱っています。ほとんどのシミュレーション ファイルは数百メガバイトに達し、開くと完全にメモリに読み込まれるように見えます。
私たちが実行する主なタスクは、ファイルのオブジェクト モデル内のすべての要素を繰り返し処理し、各要素に対して「何か」を実行することです。
最近、コード ベースを .NET 2 から VS 2010 の .NET 4 に移動したところ、反復速度が約 40 倍 (約 10 秒から約 8 分に) 低下しました。これを可能な限り最小のコード例 (10 行程度) に減らしました。これをVS 2005でコンパイルして実行し、VS 2010でプロジェクトを開いてコンパイルし、フレームワークを2のままにしました(メーカーが提供するCOM相互運用アセンブリを使用しています)。
2005 年にはテスト アプリは 10 秒で完了し、2010 年には 8 分かかりました。
何が原因でしょうか?
アップデート
コードは次と同等です。
var server = new Server();
var elements = server.Elements;
var elementCount = elements.Count;
for(int i = 0; i < elementsCount; ++i)
{
var element = elements[i];
}
このコードは、VS 2005 よりも VS 2010 で実行するのに 40 倍の時間がかかります。
更新 2
あるケースで他のケースよりも操作が大幅に遅くなる唯一の理由は、異なるバージョンでは COM を介してデータが異なる方法で転送されるためであると私は合理化しました。
両方のケースのバインド ログを記録したところ、これが見つかりました。高速バージョンでは、CustomMarshalers のネイティブ イメージが見つかりません(これらは FUSLOGVW によってキャプチャされたバインディング ログです)。
mscorlib
mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.HTM
速い
LOG: Start binding of native image mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
LOG: Start validating native image mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
WRN: Native image does not satisfy request. Looking for next native image.
WRN: No matching native image found.
遅い
LOG: Start binding of native image mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
LOG: Start validating native image mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
LOG: Bind to native image succeeded.
カスタムマーシャラー
CustomMarshalers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
速い
LOG: Start binding of native image CustomMarshalers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
LOG: Start validating native image CustomMarshalers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
WRN: Native image does not satisfy request. Looking for next native image.
WRN: No matching native image found.
遅い
LOG: Start binding of native image CustomMarshalers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
LOG: Start validating native image CustomMarshalers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
LOG: Start validating all the dependencies.
LOG: [Level 1]Start validating native image dependency mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
LOG: Dependency evaluation succeeded.
LOG: [Level 1]Start validating IL dependency Microsoft.VisualC, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
LOG: Dependency evaluation succeeded.
LOG: Validation of dependencies succeeded.
LOG: Start loading all the dependencies into load context.
LOG: Loading of dependencies succeeded.
LOG: Bind to native image succeeded.
Native image has correct version information.
Attempting to use native image C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\CustomMarshalers\3e6deccf191ab943d3a0812a38ab5c97\CustomMarshalers.ni.dll.
Native image successfully used.
したがって、ネイティブ イメージを使用しない場合、パフォーマンスが大幅に向上するようです。
このバインドがある場合には失敗し、別の場合には成功するのはなぜですか? また、アプリケーションがネイティブ イメージを使用しないようにするにはどうすればよいでしょうか?
更新 3
奇妙さは続く。このコードを VS 2010 で R# テスト ランナーまたは組み込みの Visual Studio テスト ランナーを使用したテスト メソッドで実行すると、高速で実行されます。
このコードをアセンブリにラップしてから動的にロードしようとしましたが、違いはありません。