Math.Pow与乘法运算符(性能)

Joa*_*nge 33 .net c# performance pow

任何人都知道乘法运算符是否比使用Math.Pow方法更快?喜欢:

n * n * n
Run Code Online (Sandbox Code Playgroud)

VS

Math.Pow ( n, 3 )
Run Code Online (Sandbox Code Playgroud)

ggf*_*416 42

我只是重新安装了Windows,因此没有安装visual studio并且代码很难看

using System;
using System.Diagnostics;

public static class test{

public static void Main(string[] args){
    MyTest();
    PowTest();
}

static void PowTest(){
    var sw = Stopwatch.StartNew();
    double res = 0;
    for (int i = 0; i < 333333333; i++){
        res = Math.Pow(i,30); //pow(i,30)
    }
    Console.WriteLine("Math.Pow: " + sw.ElapsedMilliseconds + " ms:  " + res);
}

static void MyTest(){
    var sw = Stopwatch.StartNew();
    double res = 0;
    for (int i = 0; i < 333333333; i++){
        res = MyPow(i,30);
    }
    Console.WriteLine("MyPow: " + sw.ElapsedMilliseconds + " ms:  " + res);
}



static double MyPow(double num, int exp)
{
    double result = 1.0;
    while (exp > 0)
    {
        if (exp % 2 == 1)
            result *= num;
        exp >>= 1;
        num *= num;
    }

    return result;
}
}
Run Code Online (Sandbox Code Playgroud)

结果:
csc/o test.cs

TEST.EXE

MyPow: 6224 ms:  4.8569351667866E+255  
Math.Pow: 43350 ms:  4.8569351667866E+255 
Run Code Online (Sandbox Code Playgroud)

平方的指数(参见/sf/ask/7100761/)比Math.Pow快得多在我的测试中(我的CPU是2 Ghz的奔腾T3200)

编辑:.NET版本是3.5 SP1,操作系统是Vista SP1和电源计划是高性能.

  • 我只是在笔记本电脑上运行了此程序,但作为.NET Core 2.1控制台应用程序,得到了以下结果:MyPow:23545 ms,Math.Pow:21109 ms。自发布以来,很明显,MS改善了性能。 (4认同)
  • MyPow()仅适用于正数.它应该以`if(exp <0)return(1/MyPow(num,Math.Abs​​(exp)))开头;` (2认同)
  • 您可以通过将模数更改为按位检查 ie (exp % 2 == 1) -&gt; ((exp &amp; 1) != 0) 来获得约 1.5% 的性能提升 (2认同)

Meh*_*ari 32

基本上,你应该基准看看.

受过教育的猜测(不可靠):

如果一些编译器没有对同一件事进行优化......

这很可能x * x * x快于Math.Pow(x, 3)作为Math.Pow具有应对其通常情况下的问题,处理分数的权力等问题,而x * x * x将只需要几个乘法指令,那么它很可能会更快.

  • 它需要两个整数乘法指​​令.如果Math.Pow没有针对相同的事情进行优化,它可能会做更多的工作(记住,它必须解决更普遍的问题,例如分数幂......) (11认同)
  • @divo:的确,这并不是猜测.之前的测试就是这样.我想指出,它确实取决于运行代码的特定基础架构,您应该始终依赖于基准测试而不是猜测. (6认同)
  • 我用“Pow(x, 2)”和“Pow(x, 3)”对此进行了基准测试。乘法始终快 100 倍以上(在调试和发布中进行了优化)。人们可以放心地选择简单的乘法而不是 Pow 函数。 (4认同)
  • 为什么你认为这很可能? (3认同)
  • "x*x*x很可能比Math.Pow快(完全猜测)." 在这句话中似乎有些东西. (3认同)
  • 我认为System.Math是作为InternalCall实现的.我没有检查过它. (2认同)

小智 7

从图像处理和科学计算的10多年优化中获得一些经验法则:

算法级别的优化在低级别上优于任何数量的优化.尽管"写明显,然后优化"的传统智慧必须在一开始就完成.不是之后.

手动编码数学运算(特别是SIMD SSE +类型)通常优于完全错误检查,广义内置算法.

编译器优化了编译器预先知道需要完成的任何操作.这些包括:1.内存操作,如Array.Copy()2.对于给定数组长度的数组上的循环.和for(..; i<array.Length;..)一样

总是设置不切实际的目标(如果你愿意).


Iam*_*mIC 7

我昨天碰巧测试了这个,然后现在看到了你的问题.

在我的机器上,运行1个测试线程的Core 2 Duo,使用倍数高达9倍.在10,Math.Pow(b,e)更快.

然而,即使在2倍的情况下,结果通常也不相同.存在舍入错误.

某些算法对舍入误差非常敏感.在我发现这一点之前,我不得不进行超过一百万次随机测试.


Hen*_*man 5

这是如此微观,您可能应该针对特定平台对其进行基准测试,我认为 Pentium Pro 的结果不一定与 ARM 或 Pentium II 相同。

总而言之,这很可能是完全无关的。