System.Runtime.InteropServices.DllImportAttribute を使用して、C# の dll から C コードを呼び出す速度をテストしていました。C 関数は、カスタム構造体を生成し、それに値を入力し、計算を行い、結果を返します。このプロセスをループで何十万回も繰り返し、ループ前とループ後のティック数を記録しました。次に、まったく同じ関数をストレート C# で作成し、この試行を繰り返しました。直接的な C# メソッドは、アンマネージ DLL を使用するよりもはるかに高速でした。なんで?管理されていないからの速度の向上はないようです。
c2cstest.c
#include <stdio.h>
struct test {
double a;
double b;
double c;
};
_declspec(dllexport) double myCfunction(double input) {
struct test one;
one.a = input;
one.b = one.a * one.a;
one.c = one.b * one.a;
return one.c;
}
cl /LD ccscstest.c runCcode.cs
using System;
using System.Runtime.InteropServices;
class test
{
[DllImport("c2cstest.dll")]
public static extern double myCfunction (double input);
static void Main()
{
double x = 5.25;
double result = 0.0;
long tick1 = DateTime.Now.Ticks;
for(int y = 100000; y > 0; y--)
{
result = myCfunction(x);
}
long tick2 = DateTime.Now.Ticks;
Console.WriteLine("Answer is {0}. Dllimport took {1} ticks.", result, tick2-tick1);
}
}
出力: 答えは 144.703125 です。Dllimport は 250000 ティックかかりました。RunCScode.cs
using System;
using System.Runtime.InteropServices;
struct test
{
public double a;
public double b;
public double c;
}
class testclass
{
double Mycsfunction (double input)
{
test one;
one.a = input;
one.b = one.a * one.a;
one.c = one.b * one.a;
return one.c;
}
static void Main()
{
double x = 5.25;
double result = 0.0;
testclass ex = new testclass();
long tick1 = DateTime.Now.Ticks;
for(int y = 100000; y > 0; y--)
{
result = ex.Mycsfunction(x);
}
long tick2 = DateTime.Now.Ticks;
Console.WriteLine("Answer is {0}. Straight CS took {1} ticks.", result, tick2-tick1);
}}
出力: 答えは 144.703125 です。ストレート CS は 50000 ティックかかりました。
追加: さまざまな方法を試した後、この人の Techniques of Calling Unmanaged Codeと同じ結論に達しましたが、彼は私よりも多くの方法を試しました。
結論: 単純な単純な関数呼び出しは価値がありません (特にループしている場合)。アンマネージ関数内にループを配置すると、確かに役立つはずです。非常に大きな関数は価値があります。さまざまな方法を試してみても、マーシャリングは効率的なテクノロジではありません。