Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/352.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#_Inline - Fatal编程技术网

C# 为什么我的正弦算法比默认算法慢得多?

C# 为什么我的正弦算法比默认算法慢得多?,c#,inline,C#,Inline,这里的交易是什么?如何使这种计算更快?我猜代码会自动识别sin算法不应该被调用,而是应该复制粘贴到循环中。我如何让编译器为我做同样的事情 另外一个问题,C++是否会对默认的SUN/COS函数进行同样的优化?如果不是,我将如何确保它是。编辑:我对它进行了测试,我的正弦函数(添加了4个额外的if条件以将域扩展到所有实数)比默认的sin函数运行快25%(尽管不准确)。事实上,复制粘贴版本的运行速度比我将其作为单独函数编写时慢。我假设您在x86上测试了此功能,因为我无法在x64上重新编制数字。在x64上

这里的交易是什么?如何使这种计算更快?我猜代码会自动识别sin算法不应该被调用,而是应该复制粘贴到循环中。我如何让编译器为我做同样的事情


另外一个问题,C++是否会对默认的SUN/COS函数进行同样的优化?如果不是,我将如何确保它是。编辑:我对它进行了测试,我的正弦函数(添加了4个额外的if条件以将域扩展到所有实数)比默认的sin函数运行快25%(尽管不准确)。事实上,复制粘贴版本的运行速度比我将其作为单独函数编写时慢。

我假设您在x86上测试了此功能,因为我无法在x64上重新编制数字。在x64上,您的代码实际上看起来更快

我反汇编了x86/release的代码。产生差异的原因在于,您的方法只是一个方法,而
Math.Sin
被编译为直接使用x86
fsin
指令,从而消除了每次调用的函数调用

FWIW,x64代码是完全不同的
Math.Sin
被翻译成
clr!COMDouble::Sin


请参阅。

您是否运行了程序的“发布”版本?如果没有,那么您的函数可能没有内联。您的意思是,当您将代码复制粘贴到主函数中时,您与
mysin
的时间与
Math.Sin
的时间相同吗?是的,我在发布模式下的时间相同。在调试模式下,复制粘贴的power series实际上要快4倍;编译器将在衬里中执行代码(用函数调用替换函数代码体)。不确定在这种情况下是什么意思。您还可以尝试在函数中添加以下属性:
[MethodImpl(methodimpoptions.acgressiveinline)]
(从
System.Runtime.CompilerServices
命名空间)我的计算机是64位计算机,我不记得将visual studio显式配置为32位或64位。默认情况下,VS为任何CPU生成x86代码-检查您的项目设置-应选中“首选32位”。进行否决表决时,请留下评论。谢谢。我的电脑是64位的,当我运行它时选择了“首选32位”选项,这表明OP的方法比Math快3倍。Sin。@Fabjan是发布模式的,并且运行时没有附加调试程序吗?
const double pi = 3.1415926535897;

static double mysin(double x) {
    return ((((((-0.000140298 * x - 0.00021075890) * x + 0.008703147) * x -
        0.0003853080) * x - 0.16641544) * x - 0.00010117316) * x +
        1.000023121) * x;
}

static void Main(string[] args) {
    Stopwatch sw = new Stopwatch();

    double a = 0;
    double[] arg = new double[1000000];
    for (int i = 0; i < 1000000; i++) {
        arg[i] = (pi / 2000000);
    } 
    sw.Restart();
    for (int i = 0; i < 1000000; i++) {
        a = a + Math.Sin(arg[i]);
    }
    sw.Stop();
    double t1 = (double)(sw.Elapsed.TotalMilliseconds);

    a = 0;
    sw.Restart();
    for (int i = 0; i < 1000000; i++) {
        a = a + mysin(arg[i]);
    }
    sw.Stop();
    double t2 = (double)(sw.Elapsed.TotalMilliseconds);
    Console.WriteLine("{0}\n{1}\n", t1,t2);
    Console.Read(); 
}
a = 0;
sw.Restart();
for (int i = 0; i < 1000000; i++) {
    double x = arg[i];
    a = a + ((((((-0.000140298 * x - 0.00021075890) * x + 0.008703147) * x -
        0.0003853080) * x - 0.16641544) * x - 0.00010117316) * x +
        1.000023121) * x;
    //a = a + mysin(arg[i]);
}