はじめに
.NET のアンマネージドメモリの処理速度 について調べていたところ、以下の記事を見つけました。
AllocHGlobalとAllocCoTaskMem どちらを使うべきか?
私はこの記事に出会うまで AllocCoTaskMem の存在を知らなかったので、何も考えず AllocHGlobal を使ってきたのですが、記事を読んだところ以下の結論になっていました。
「パフォーマンス的に多少の前後はあるが、AllocHGlobalとAllocCoTaskMemに大きな違いはあまりない。
LocalAllocは互換性維持のために残されていることから、特別な理由がない限り、AllocCoTaskMemを利用したほうが好ましい。」
そ、そんな… 今日まで AllocHGlobal を使ってきたのに… きっと AllocHGlobal にも良いところがあるはずだ!
@Nuits さんの処理速度ベンチマークでは 0.1msecオーダーで ぴったり同じ結果になっているが、usecオーダーなら AllocHGlobal の方が高速なはずだ! 頼むから何か取り柄があってくれ!!
ってことで BenchmarkDotNet を使って、処理時間を計測しました。
測定方法
@Nuits さんの計測で 100Byte だったメモリを10MByte に拡張してみました。
public class AllocateMemory
{
private const int AllocSize = 10 * 1024 * 1024;
[Benchmark]
public void AllocHGlobal()
{
IntPtr intPtr = Marshal.AllocHGlobal(AllocSize);
Marshal.FreeHGlobal(intPtr);
}
[Benchmark]
public void AllocCoTaskMem()
{
IntPtr intPtr = Marshal.AllocCoTaskMem(AllocSize);
Marshal.FreeCoTaskMem(intPtr);
}
}
測定結果
Method | Mean | Error | StdDev |
---|---|---|---|
AllocHGlobal | 182.2 us | 56.12 us | 3.08 us |
AllocCoTaskMem | 179.4 us | 21.47 us | 1.18 us |
元記事の通り大差はありませんでしたが、僅かに(1.5%) AllocCoTaskMem の方が高速でした。
互換性 だけでなく、処理速度の観点からも AllocCoTaskMem が優れていますので、AllocHGlobal の使用は今すぐ辞めましょう。
なんでこれまで AllocHGlobal を使ってたんだろうか。がっくり来ました。