Wankuma.Interop.InteropQueryPerformanceCounter Version1
わんくまライブラリ Wankuma.Interop.InteropQueryPerformanceCounter Version1より
えーっと、ダウンロードしてないです、ソースは Web からみれるものを1枚見ただけ
P/Ivoke の戻り値が short になっていますが API の定義は Windows Types BOOL 型なので、対応する .NET 型は UnmanagedType.Bool へマッピングされなければなりません。これは標準では System.Int32 になっています。この場合は MarshalAsAttribute を利用して
private static extern [MarshalAs(UnmanagedType.Bool)]bool ....
と、戻値のマーシャリング型を指定することで .NET 側から透過的に真偽判定を行うことができます。個人的には、P/Invoke の定義は開発ガイドに従って
public class PerformanceCounter { // マネージドインターフェスとしての QueryPerfomanceCounter の定義 public long PerformanceCounter { get { long value; if (NativeMethods.QueryPerformanceCounter(ref value) != 0) { return value; } // GenerateWin32Exception("QueryPerfomanceCounter", Marshal.GetLastWin32Error()); throw new NotSupportException(); } } // ネイティブインターフェスの定義は NativeMethods というインナークラスに配置する private class NativeMethods { // マネージドインターフェスを別途定義する前提で、API 定義は Win32 に // 対して素直な形で定義する。例えば /// <return>If the function succeeds, the return value is nonzero.</return> // という定義なので、nonzero を判定できる int で定義する。 public static extern int QueryPerformanceCounter(ref long counter); } }
と、NativeMethods クラスを経由するべきかもしれません。さらに QueryPerformanceCounter という API の要求から、現状の Web に掲載されているコードではオーバーヘッドが高すぎて分解度と計測誤差が大きく差がでてしまっています。
[SuppressUnmanagedCodeSecurity] private class NativeMethods
と、セキュリティチェックをすっとばし、*1blittable 型のデータマーシャリングにおけるスタック上の変換を無効化し、
[SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] or/and new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
のように、別経路でのセキュリティチェックを施すことで、API の性能をある程度引き出すことができるようになるでしょう。*2 *3
何も見ないで書いているため、コンパイルできないコードを提示している可能性がありますが、何が必要なのかはわかるだろうから気にしないことにします(苦笑