C-for-loop在C for-loop上的较大范围的降级性能

时间:2013-02-19 09:12:26

标签: c# c performance for-loop unmanaged

当我从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性能表现良好......

现在,我认为测试的评估是错误的还是预期的性能结果?

1 个答案:

答案 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毫秒。

开销似乎有点大,但我猜测量数据存在一些不准确之处。