|
Hongliang さん
回答ありがとうございます。
> この文脈における固定配列は、fixedキーワードを使った固定サイズバッファを指すはずです。
なるほど!!!「固定配列」という文言がどこにもなかったので fixedをするという概念がありませんでした。 試しに同じようなサイズをもたせた構造体を用意し、 マーシャリング指定と固定配列の動作を確認してみました。
◆構造体宣言 [StructLayout( LayoutKind.Sequential )] public struct BlittableIntStructMemCopy { public fixed byte Array1[20000]; public fixed byte Array2[20000]; public fixed byte Array3[20000]; }
[StructLayout( LayoutKind.Sequential )] public struct BlittableIntStruct { [MarshalAs( UnmanagedType.ByValArray, SizeConst = 20000 )] public byte[] Array1; [MarshalAs( UnmanagedType.ByValArray, SizeConst = 20000 )] public byte[] Array2; [MarshalAs( UnmanagedType.ByValArray, SizeConst = 20000 )] public byte[] Array3; }
◆呼び出し [DllImport( "FooFuncsDll.dll", EntryPoint="BlittableInt" )] public extern static int BlittableInt( [In] ref BlittableIntStruct objStruct ); [DllImport( "FooFuncsDll.dll", EntryPoint="BlittableInt" )] private extern static int BlittableIntPointer( ref BlittableIntStructMemCopy pointer );
※どちらも[In]属性のみ DLL呼び出しを5000回ループさせる。
◆DLLの中身(C++) 構造体に適当な値を放り込むだけ
◆結果 5000回実行の経過時間 マーシャリングありの方は 0.0471秒 (1件当り0.00942ミリ秒) fixedキーワードの構造体 0.0107秒 (1件当り0.00214ミリ秒)
かつ、マーシャリングありの方は構造体がnullのままで、 fixedはメモリコピーが発生していると考えられ、 構造体の内容が書き換わっていました。
> レガシーっていうと違和感。 > どういう想定において近いパフォーマンスというのかよく判りません。
すみません、VB6からC++で実装されたDLLを呼び出した時の時間と、C#で呼び出した時の経過時間が あまりにも違うので疑問に思っておりました。(C++の関数の実装は、構造体のポインタを渡す) VB6は単純に構造体を VarPtr(objStruct)として渡していて、 C#の方はref渡しすればポインタの参照か値渡しになると解釈していたのですが マーシャリングやメモリ固定の挙動を調べていくうちに、どういった事ができるのか? という疑問が発生していました。
> // 結局マネージで処理したいのかアンマネージで処理したいのかどっちなんだろ…。
今回質問させていただいたのは、どちらでも・・・なんです。 ただ例えば、byte配列を操作する時、「速度のみ」を追い求めた時にやっぱり 低級言語には勝てないのかなと。。。思いました。
|