Pergunta

Qualquer um sabe se o operador multiplicar é mais rápido do que usando o método Math.pow? Como:

n * n * n

vs

Math.Pow ( n, 3 )
Foi útil?

Solução

Basicamente, você deve referência para ver.

Educado Guesswork (não confiável):

No caso não é otimizado para a mesma coisa por algum compilador ...

É muito provável que x * x * x é mais rápido que Math.Pow(x, 3) como Math.Pow tem de lidar com o problema em seu caso geral, lidar com potências fracionárias e outras questões, enquanto x * x * x seria apenas levar um par instruções multiplicam, por isso é muito provável que seja mais rápido .

Outras dicas

I apenas janelas reinstalados modo visual studio não está instalado eo código é feio

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

Os resultados:
csc / o test.cs

test.exe

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

A exponenciação por quadratura (veja https://stackoverflow.com/questions/101439/the-most-efficient-way-to-implement-an-integer-based-power-function-powint-int ) é muito mais rápido do que matemática. Pow no meu teste (meu CPU é um T3200 Pentium a 2 Ghz)

EDIT:. Versão .NET é 3.5 SP1, OS é Vista SP1 e plano de energia é alto desempenho

Algumas regras de ouro de 10 anos de otimização em processamento de imagens e computação científica:

otimizações em um nível algorítmico vencer qualquer quantidade de otimização em um nível baixo. Apesar da "Escrever o óbvio, em seguida, otimizar" a sabedoria convencional isso deve ser feito no início. Não depois.

operações matemáticas codificadas manualmente (especialmente SIMD SSE + tipos) geralmente superar o erro totalmente marcada, generalizada embutido queridos.

Qualquer operação em que o compilador sabe de antemão o que precisa ser feito são otimizadas pelo compilador. Esses incluem: 1. As operações de memória, tais como Array.Copy () 2. Para ciclos mais matrizes em que o comprimento de matriz é dado. Como em para (..; i<array.Length;..)

Sempre definir metas irrealistas (se você quiser).

Aconteceu de eu testei isso ontem, em seguida, viu a sua pergunta agora.

Na minha máquina, um Core 2 Duo rodando 1 fio de teste, é mais rápido usar multiplicar até um factor de 9. Aos 10, Math.pow (b, e) é mais rápido.

No entanto, mesmo com um fator de 2, os resultados muitas vezes não são idênticos. Há erros de arredondamento.

Alguns algoritmos são altamente sensíveis a erros de arredondamento. Eu tive que literalmente atropelado um milhão de testes aleatórios até que eu descobri isso.

Eu verifiquei, e Math.Pow() está definido para tomar duas duplas. Isso significa que ele pode não multiplicações repetido, mas tem que usar uma abordagem mais geral. Se houvesse uma Math.Pow(double, int), ele provavelmente poderia ser mais eficiente.

Dito isto, a diferença de desempenho é quase certamente absolutamente trivial, e por isso você deve usar o que for mais clara. Micro-otimizações como este são quase sempre inútil, pode ser introduzida em praticamente qualquer hora, e deve ser deixado para o final do processo de desenvolvimento. Nesse ponto, você pode verificar se o software é muito lento, onde os pontos quentes são, e gastar o seu esforço micro-otimização, onde ele vai realmente fazer a diferença.

Isto é tão micro que você provavelmente deve benchmark para plataformas específicas, eu não acho que os resultados para um Pentium Pro será necessariamente o mesmo que para um braço ou Pentium II.

Em suma, é mais provável que seja totalmente irrelevante.

Vamos usar a convenção x ^ n. Vamos supor que n é sempre um inteiro.

Para pequenos valores de n, chato multiplicação será mais rápido, porque Math.pow (provavelmente, dependente de implementação) utiliza algoritmos sofisticados para permitir a n ser não-integral e / ou negativo.

Para grandes valores de n, Math.pow provavelmente será mais rápido, mas se sua biblioteca não é muito inteligente ele usará o mesmo algoritmo, que não é ideal se você sabe que n é sempre um inteiro. Para isso você pode codificar-se uma implementação de exponenciação por quadratura ou algum outro algoritmo de fantasia.

É claro que os computadores modernos são muito rápidos e você provavelmente deve manter o mais simples, mais fácil de ler, menos provável de ser um método de buggy até que você comparar o seu programa e temos a certeza que você vai ter uma aceleração significativa usando um algoritmo diferente.

Eu discordo que funciona handbuilt são sempre mais rápido. As funções de co-seno são a maneira mais rápida e mais precisa do que qualquer coisa que eu poderia escrever. Quanto POW (). Eu fiz um teste rápido para ver como lento Math.pow () estava em javascript, porque Mehrdad advertiu contra adivinhação

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

aqui estão os 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

Se você não concordar experimentar o programa em http: //www.m0ose. com / javascripts / speedtests / powSpeedTest.html

Math.Pow(x, y) é normalmente calculado internamente como Math.Exp(Math.Log(x) * y). Evey equação do poder exige encontrar um log natural, uma multiplicação, e levantando e a uma potência.

Como mencionei na minha resposta anterior, apenas com uma potência de 10 não Math.Pow() se tornar mais rápido, mas a precisão será comprometida se usando uma série de multiplicações.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top