Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#:为什么函数调用比手动内联更快?_C#_Performance_Release_Inline_Inline Code - Fatal编程技术网

C#:为什么函数调用比手动内联更快?

C#:为什么函数调用比手动内联更快?,c#,performance,release,inline,inline-code,C#,Performance,Release,Inline,Inline Code,我测量了计算2的幂的两种方法的执行时间: 1)内联 result = b * b; 2)通过简单的函数调用 result = Power(b); 在调试模式下运行时,一切都如预期的那样:调用一个函数比在线计算要昂贵得多(在线385毫秒,而在线570毫秒函数调用) 在发布模式下,我希望编译器能大大加快函数调用的执行速度,因为编译器会在内部内联非常小的Power()函数。但我不希望函数调用比手动内联计算更快 最令人惊讶的是,在发布版本中,第一次运行需要109毫秒,第二次运行调用Power()只需

我测量了计算2的幂的两种方法的执行时间:

1)内联

result = b * b;
2)通过简单的函数调用

result = Power(b);
在调试模式下运行时,一切都如预期的那样:调用一个函数比在线计算要昂贵得多(在线385毫秒,而在线570毫秒函数调用)

在发布模式下,我希望编译器能大大加快函数调用的执行速度,因为编译器会在内部内联非常小的
Power()
函数。但我不希望函数调用比手动内联计算更快

最令人惊讶的是,在发布版本中,第一次运行需要109毫秒,第二次运行调用
Power()
只需要62毫秒

函数调用如何比手动内联更快?

以下是供您复制的程序:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Starting Test");

        // 1. Calculating inline without function call
        Stopwatch sw = Stopwatch.StartNew();

        for (double d = 0; d < 100000000; d++)
        {
            double res = d * d;
        }

        sw.Stop();
        Console.WriteLine("Checked: " + sw.ElapsedMilliseconds);

        // 2. Calulating power with function call
        Stopwatch sw2 = Stopwatch.StartNew();

        for (int d = 0; d < 100000000; d++)
        {
            double res = Power(d);
        }

        sw2.Stop();
        Console.WriteLine("Function: " + sw2.ElapsedMilliseconds);

        Console.ReadKey();
    }

    static double Power(double d)
    {
        return d * d;
    }
}
类程序
{
静态void Main(字符串[]参数)
{
控制台写入线(“启动测试”);
//1.在不调用函数的情况下计算内联
秒表sw=Stopwatch.StartNew();
对于(双d=0;d<100000000;d++)
{
双精度=d*d;
}
sw.Stop();
控制台写入线(“选中:+sw.ElapsedMilliseconds”);
//2.使用函数调用计算功率
Stopwatch sw2=Stopwatch.StartNew();
对于(int d=0;d<100000000;d++)
{
双res=功率(d);
}
sw2.Stop();
Console.WriteLine(“函数:+sw2.ElapsedMilliseconds”);
Console.ReadKey();
}
静态双电源(双d)
{
返回d*d;
}
}

您的测试错误。在第二部分中,使用
intd
而不是double。也许这可以解释时差。

正如Xavier正确指出的那样,您在一个循环中使用double,在另一个循环中使用int。将两者更改为相同的类型将使结果相同-我测试了它


此外:您在这里真正衡量的是添加和比较的持续时间。您没有测量
d
平方的持续时间,因为它根本没有发生:在发布版本中,优化器完全删除循环体,因为没有使用结果。您可以通过注释循环体来确认这一点。持续时间将是相同的。

Daniel Hilgarth是正确的,由于未使用的结果,根本不会进行计算(在调试模式下可能不是这种情况)。尝试以下示例,您将得到正确的结果:

static void Main(string[] args)
    {
        Console.WriteLine("Starting Test");
        var list = new List<int>();
        // 1. Calculating inline without function call
        Stopwatch sw = Stopwatch.StartNew();

        for (int d = 0; d < 100000000; d++)
        {
            int res = d * d;
            list.Add(res);
        }

        sw.Stop();
        Console.WriteLine("Checked: " + sw.ElapsedMilliseconds);
        // 2. Calulating power with function call

        list = new List<int>();
        Stopwatch sw2 = Stopwatch.StartNew();

        for (int d = 0; d < 100000000; d++)
        {
            int res = Power(d);
            list.Add(res);
        }

        sw2.Stop();
        Console.WriteLine("Function: " + sw2.ElapsedMilliseconds);

        Console.ReadKey();
    }
static void Main(字符串[]args)
{
控制台写入线(“启动测试”);
var list=新列表();
//1.在不调用函数的情况下计算内联
秒表sw=Stopwatch.StartNew();
对于(int d=0;d<100000000;d++)
{
int res=d*d;
列表。添加(res);
}
sw.Stop();
控制台写入线(“选中:+sw.ElapsedMilliseconds”);
//2.使用函数调用计算功率
列表=新列表();
Stopwatch sw2=Stopwatch.StartNew();
对于(int d=0;d<100000000;d++)
{
int res=功率(d);
列表。添加(res);
}
sw2.Stop();
Console.WriteLine(“函数:+sw2.ElapsedMilliseconds”);
Console.ReadKey();
}

您是否在调试器(F5)下启动了程序?在这种情况下,优化被抑制。您是在发布模式下运行生成的.exe还是在VS中运行的?还有,你试过按不同的顺序给他们打电话吗?我发现这有一个微妙的区别。那么,为什么使用int作为double比使用double快呢?@Vercas:很可能是因为递增和比较double更昂贵。@DanielHilgarth啊,好的一点……在我的计算机上,函数一的运行时间总是比内联函数慢(无论是int还是double).修复后的结果是什么?@RobertNiestroj:请看我的答案,也完全正确。这是我的错误。我曾经监督过INT,这段代码是否会抛出一个
OverflowException
,因为
res
最终会在这些循环中远远超过
Int32.MaxValue