views:

1941

answers:

5

Anyone knows if multiply operator is faster than using the Math.Pow method? Like:

n * n * n

vs

Math.Pow ( n, 3 )
+8  A: 

Basically, you should benchmark to see.

Educated Guesswork (unreliable):

In case it's not optimized to the same thing by some compiler...

It's very likely that x * x * x is faster than Math.Pow(x, 3) as Math.Pow has to deal with the problem in its general case, dealing with fractional powers and other issues, while x * x * x would just take a couple multiply instructions, so it's very likely to be faster.

Mehrdad Afshari
why do you believe this to be very likely?
Demi
It takes two integer multiply instructions. In case Math.Pow is not optimized out to the same thing, it probably does much more work (remember, it has to solve a much more general problem, such as fractional powers...)
Mehrdad Afshari
"It's very likely that x * x * x is faster than Math.Pow (completely guesswork)."Something seems off in this sentence.
Svend
I noticed MS also used * all over xna, so wondered about it.
Joan Venge
You can always open up System.Math in reflector and check it out. My personal guess is that there's more overhead (possibly negligible granted)to allow it to be a general purpose function, rather than a discrete mathematical calculation.
Ian Jacobs
I think System.Math is implemented as InternalCall. I haven't checked it though.
Mehrdad Afshari
@Mehrdad: Thanks for the additional explanation - I have no disagreement.
Demi
@divo: Indeed, it wasn't really guesswork. It was previous tests that resulted this. I wanted to point out that it really depends on the particular infrastructure that's running your code and you should always rely on benchmarking rather than guessing.
Mehrdad Afshari
+4  A: 

Here is a discussion on the topic of inlined multiplication vs. Math.pow

Apparently Math.pow is slower, but not by much...

Demi
+2  A: 

I checked, and Math.Pow() is defined to take two doubles. This means that it can't do repeated multiplications, but has to use a more general approach. If there were a Math.Pow(double, int), it could probably be more efficient.

That being said, the performance difference is almost certainly absolutely trivial, and so you should use whichever is clearer. Micro-optimizations like this are almost always pointless, can be introduced at virtually any time, and should be left for the end of the development process. At that point, you can check if the software is too slow, where the hot spots are, and spend your micro-optimization effort where it will actually make a difference.

David Thornley
+1  A: 

Let's use the convention x^n. Let's assume n is always an integer.

For small values of n, boring multiplication will be faster, because Math.Pow (likely, implementation dependent) uses fancy algorithms to allow for n to be non-integral and/or negative.

For large values of n, Math.Pow will likely be faster, but if your library isn't very smart it will use the same algorithm, which is not ideal if you know that n is always an integer. For that you could code up an implementation of exponentiation by squaring or some other fancy algorithm.

Of course modern computers are very fast and you should probably stick to the simplest, easiest to read, least likely to be buggy method until you benchmark your program and are sure that you will get a significant speedup by using a different algorithm.

David
+2  A: 

I just reinstalled windows so visual studio is not installed and the code is ugly

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;
}
}

The results:
csc /o test.cs

test.exe
MyPow: 6224 ms: 4.8569351667866E+255
Math.Pow: 43350 ms: 4.8569351667866E+255

Exponentiation by squaring (see http://stackoverflow.com/questions/101439/the-most-efficient-way-to-implement-an-integer-based-power-function-powint-int) is much faster than Math.Pow in my test (my CPU is a Pentium T3200 at 2 Ghz)

EDIT: .NET version is 3.5 SP1, OS is Vista SP1 and power plan is high performance.

ggf31416
Thanks. Your method seems very good. Is it even better than n*n*n?
Joan Venge
It requires two multiplications, just like n*n*n, but with some overhead, so it will be slightly worse... For an exponent of four (or higher) it may be better than n*n*n*n though, as it still requires only two multiplications, while the direct approach needs three.
Jaime