Matemáticas.Pow vs multiplicar operador (rendimiento)


Cualquiera sabe si el operador multiplicar es más rápido que usar las matemáticas.Método Pow? Como:

n * n * n

Vs

Math.Pow ( n, 3 )
Author: Deduplicator, 2009-06-02

10 answers

Básicamente, debes comparar para ver.

Conjeturas educadas (poco fiables):

En caso de que no esté optimizado para lo mismo por algún compilador...

Es muy probable que x * x * x sea más rápido que Math.Pow(x, 3) ya que Math.Pow tiene que lidiar con el problema en su caso general, tratando con potencias fraccionarias y otros temas, mientras que x * x * x solo tomaría un par de instrucciones de multiplicación, por lo que es muy probable que sea más rápido.

 23
Author: Mehrdad Afshari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-01 20:24:59

Acabo de reinstalar Windows para que visual studio no esté instalado y el código sea feo

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

Los resultados:
prueba csc /o.cs

Prueba.exe

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

Exponenciación por cuadratura (ver https://stackoverflow.com/questions/101439/the-most-efficient-way-to-implement-an-integer-based-power-function-powint-int) es mucho más rápido que las matemáticas.Pow en mi prueba (mi CPU es un Pentium T3200 a 2 Ghz)

EDITAR: La versión. NET es 3.5 SP1, el sistema operativo es Vista SP1 y el poder el plan es de alto rendimiento.

 32
Author: ggf31416,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:30

Acabo de probar esto ayer, luego vi tu pregunta ahora.

En mi máquina, un Core 2 Duo ejecutando 1 hilo de prueba, es más rápido usar multiplicar hasta un factor de 9. A los 10, Matemáticas.Pow (b, e) es más rápido.

Sin embargo, incluso en un factor de 2, los resultados a menudo no son idénticos. Hay errores de redondeo.

Algunos algoritmos son muy sensibles a los errores de redondeo. Tuve que ejecutar literalmente más de un millón de pruebas aleatorias hasta que descubrí esto.

 6
Author: IamIC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-20 12:10:47

Algunas reglas empíricas de más de 10 años de optimización en procesamiento de imágenes y computación científica:

Las optimizaciones a nivel algorítmico superan cualquier cantidad de optimización a un nivel bajo. A pesar de la" Escribir lo obvio, a continuación, optimizar " sabiduría convencional esto debe hacerse al principio. No después.

Las operaciones matemáticas codificadas a mano (especialmente los tipos SIMD SSE+) generalmente superarán a las operaciones integradas generalizadas y completamente verificadas.

Cualquier operación donde el compilador sabe de antemano lo que hay que hacer son optimizados por el compilador. Estos incluyen: 1. Operaciones de memoria como Array.Copia() 2. Para bucles sobre matrices donde se da la longitud de la matriz. Como en para (..; i<array.Length;..)

Siempre establece metas poco realistas (si quieres).

 5
Author: Doug,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-09 05:55:14

He comprobado, y Math.Pow() se define para tomar dos dobles. Esto significa que no puede hacer multiplicaciones repetidas, sino que tiene que usar un enfoque más general. Si hubiera un Math.Pow(double, int), probablemente podría ser más eficiente.

Dicho esto, la diferencia de rendimiento es casi seguramente absolutamente trivial, por lo que debe usar lo que sea más claro. Micro-optimizaciones como esta son casi siempre inútiles, se pueden introducir en prácticamente cualquier momento, y deben dejarse para el final de la proceso de desarrollo. En ese punto, puede verificar si el software es demasiado lento, dónde están los puntos calientes, y gastar su esfuerzo de microoptimización donde realmente hará una diferencia.

 4
Author: David Thornley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-01 20:29:30

Esto es tan micro que probablemente deberías compararlo para plataformas específicas, no creo que los resultados para un Pentium Pro sean necesariamente los mismos que para un ARM o Pentium II.

En general, es muy probable que sea totalmente irrelevante.

 4
Author: Henk Holterman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-01 21:57:33

Usemos la convención x^n. Asumamos que n es siempre un entero.

Para valores pequeños de n, la multiplicación aburrida será más rápida, porque las matemáticas.Pow (probable, dependiente de la implementación) utiliza algoritmos sofisticados para permitir que n sea no integral y / o negativo.

Para valores grandes de n, Matemáticas.Pow probablemente será más rápido, pero si su biblioteca no es muy inteligente, utilizará el mismo algoritmo, lo cual no es ideal si sabe que n es siempre un entero. Para que usted podría codificar un implementación de exponenciación por cuadratura o algún otro algoritmo de fantasía.

Por supuesto, las computadoras modernas son muy rápidas y probablemente debería atenerse al método más simple, más fácil de leer y menos probable que tenga errores hasta que compare su programa y esté seguro de que obtendrá una aceleración significativa utilizando un algoritmo diferente.

 2
Author: David,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-01 20:39:22

Aquí hay una discusión sobre el tema de multiplicación en línea vs.Matemáticas.pow

Aparentemente matemáticas.pow es más lento, pero no por mucho...
 1
Author: Demi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-01 20:21:28

No estoy de acuerdo en que las funciones handbuilt siempre son más rápidas. Las funciones de coseno son mucho más rápidas y precisas que cualquier cosa que pudiera escribir. En cuanto a pow (). Hice una prueba rápida para ver qué tan lenta era la matemática.pow () estaba en javascript, porque Mehrdad advirtió contra conjeturas

    for (i3 = 0; i3 < 50000; ++i3) { 
      for(n=0; n < 9000;n++){ 
        x=x*Math.cos(i3);
      }
    }

Aquí están los resultados:

Each function run 50000 times 

time for 50000 Math.cos(i) calls = 8 ms 
time for 50000 Math.pow(Math.cos(i),9000) calls = 21 ms 
time for 50000 Math.pow(Math.cos(i),9000000) calls = 16 ms 
time for 50000 homemade for loop calls 1065 ms

Si no estás de acuerdo, prueba el programa en http://www.m0ose.com/javascripts/speedtests/powSpeedTest.html

 1
Author: dooder duderama,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-20 18:31:37

Math.Pow(x, y) normalmente se calcula internamente como Math.Exp(Math.Log(x) * y). Cada ecuación de potencia requiere encontrar un logaritmo natural, una multiplicación y elevar e a una potencia.

Como mencioné en mi respuesta anterior, solo con una potencia de 10 Math.Pow() se hace más rápido, pero la precisión se verá comprometida si se usa una serie de multiplicaciones.

 0
Author: IamIC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-22 09:22:53