当我从C#调用ummanaged dll时,我已经对C#和C中的for循环的性能进行了一些测试......
结果让我感到惊讶的是,当循环越过更大的范围时,C#的性能与C相比有所降低。对于较小的范围,C#表现出优于C的性能....但是,作为上限范围for循环增加,与C ....相比,C#性能下降。
这是我的测试代码......
[DllImport("Testing.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int SumLoop(int lowLimit, int highLimit);
public static void Main(string[] args)
{
const int LowerRange = 1;
const int HigherRange = 1000000;
// Test with C# For Loop
var watch1 = new Stopwatch();
watch1.Start();
int sum = 0;
for (int i = LowerRange; i <= HigherRange; i++)
{
sum += i;
}
watch1.Stop();
long elapseTime1 = watch1.ElapsedMilliseconds;
// Test with C-for loop
var watch2 = new Stopwatch();
watch2.Start();
int sumFromC = SumLoop(LowerRange , HigherRange);
long elapseTime2 = watch2.ElapsedMilliseconds;
}
Testing.dll:
__declspec(dllexport) int SumLoop(int lowLimit, int highLimit)
{
int idx;
int totalSum = 0;
for(idx = lowLimit;idx<= highLimit; idx= idx +1)
{
totalSum += idx;
}
return totalSum;
}
测试结果:
测试1:
HigherRange:1000000
C#循环:4毫秒
C-loop:9毫秒
测试2:
HigherRange:10000000
C#循环:53毫秒
C环:36毫秒
测试3:
HigherRange:100000000
C#循环:418毫秒
C循环:343毫秒
在这里,我开始进行上述测试,目的是C for-loop性能优于C#循环,但它与我的理解完全相反,并且与question一致并且同意......但是当我增加时在for循环的上限范围内,与C#相比,C性能表现良好......
现在,我认为测试的评估是错误的还是预期的性能结果?
答案 0 :(得分:3)
这里发生的是你忽略了使用P / Invoke调用C函数的固定开销。
C函数将比C#版本BUT更快,因为调用它的开销相对较大,对于小型数组,C函数似乎会更慢,因为调用开销相对较大总时间的比例。
然而,当您增加集合的大小时,开销将占总时间的一小部分,直到C版本的额外速度断言并且您开始看到它运行得更快。
如果你看一下C#函数的时间,你可以看到它确实或多或少地与N线性增长,这是你期望的。将N增加100倍后,将T = 4与T = 418进行比较。正是您所期望的。但由于上述原因,C时间似乎没有线性增加。
顺便提一下,如果您至少进行两次计时,则可以使用联立方程式来解决:
T = K + XN
其中K是固定开销,X是每个元素的开销。
我从你的时间计算出,调用非托管代码的固定开销大约是5.6毫秒,每个元素的开销是3.373737 x 10 ^ -6毫秒。
开销似乎有点大,但我猜测量数据存在一些不准确之处。