Math.Pow против оператора умножения (производительность)

CREATE TRIGGER sample_trigger_msg 
    BEFORE INSERT
FOR EACH ROW
    BEGIN
IF(NEW.important_value) < (1*2) THEN
    DECLARE dummy INT;
    SELECT 
           Enter your Message Here!!!
 INTO dummy 
        FROM mytable
      WHERE mytable.id=new.id
END IF;
END;
29
задан Deduplicator 8 March 2015 в 01:03
поделиться

10 ответов

По сути, вы должны проверить , чтобы увидеть.

Обученный Guesswork (ненадежный):

На случай, если какой-то компилятор его не оптимизирует ...

Весьма вероятно, что x * x * x быстрее, чем Math.Pow(x, 3), поскольку Math.Pow должен решать проблему в общем случае, касающуюся дробных степеней и других вопросов, в то время как x * x * x просто потребует пара умножает инструкции, поэтому, скорее всего, это будет быстрее.

29
ответ дан Mehrdad Afshari 8 March 2015 в 01:03
поделиться

Несколько эмпирических правил из 10+ лет оптимизации в обработке изображений & amp; научные вычисления:

Оптимизация на алгоритмическом уровне превосходит любое количество оптимизации на низком уровне. Несмотря на общепринятое мнение «напиши очевидное, а затем оптимизируй», это необходимо сделать с самого начала. Не после.

Математические операции с ручным кодированием (особенно SIMD SSE +) обычно превосходят полностью проверенные встроенные встроенные ошибки.

Любая операция, в которой компилятор заранее знает, что нужно сделать, оптимизируется компилятором. К ним относятся: 1. Операции с памятью, такие как Array.Copy (). 2. Для циклов над массивами, где указана длина массива. Как и для (..; i<array.Length;..)

Всегда ставьте нереальные цели (если хотите).

7
ответ дан Joan Venge 8 March 2015 в 01:03
поделиться

Я только что проверил это вчера, а потом увидел ваш вопрос.

На моей машине, Core 2 Duo, на которой запущен 1 тестовый поток, быстрее использовать умножение с коэффициентом 9. В 10 Math.Pow (b, e) быстрее.

Однако, даже в 2 раза, результаты часто не идентичны. Есть ошибки округления.

Некоторые алгоритмы очень чувствительны к ошибкам округления. Мне пришлось буквально выполнить более миллиона случайных тестов, пока я не обнаружил это.

6
ответ дан IamIC 8 March 2015 в 01:03
поделиться

Я только что переустановил 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;
}
}

Результаты:
csc / o test.cs

test. exe

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

Возведение в степень путем возведения в квадрат (см. https://stackoverflow.com/questions/101439/the-most-efficient-way-to-implement-an-integer-based-power- function-powint-int ) намного быстрее, чем Math.Pow в моем тесте (мой процессор - Pentium T3200 с частотой 2 ГГц)

РЕДАКТИРОВАТЬ: .NET версия 3.5 SP1, ОС Vista Vista SP1 и План питания - высокая производительность.

40
ответ дан Community 8 March 2015 в 01:03
поделиться

Я проверил, и Math.Pow() определен, чтобы взять две пары. Это означает, что он не может делать повторные умножения, но должен использовать более общий подход. Если бы был Math.Pow(double, int), он мог бы быть более эффективным.

Тем не менее, разница в производительности почти наверняка абсолютно тривиальна, и поэтому вы должны использовать то, что яснее. Подобные микрооптимизации почти всегда бессмысленны, их можно вводить практически в любое время, и их следует оставить для завершения процесса разработки. В этот момент вы можете проверить, не слишком ли медленно работает программное обеспечение, где находятся «горячие точки», и провести свои усилия по микрооптимизации там, где это действительно будет иметь значение.

4
ответ дан David Thornley 8 March 2015 в 01:03
поделиться

Это настолько микро, что вам, вероятно, стоит сравнить его с конкретными платформами, я не думаю, что результаты для Pentium Pro будут обязательно такими же, как для ARM или Pentium II.

В целом, это, скорее всего, совершенно не имеет значения.

4
ответ дан Henk Holterman 8 March 2015 в 01:03
поделиться

Я не согласен с тем, что встроенные функции всегда быстрее. Функции косинуса намного быстрее и точнее, чем все, что я мог написать. Что касается Pow (). Я сделал быстрый тест, чтобы увидеть, насколько медленным был Math.pow () в javascript, потому что Мехрдад предостерегал от догадок

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

вот результаты:

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

Не согласитесь, попробуйте программу на http://www.m0ose.com/javascripts/speedtests/powSpeedTest.html

1
ответ дан dooder duderama 8 March 2015 в 01:03
поделиться

Math.Pow(x, y) обычно рассчитывается внутри как Math.Exp(Math.Log(x) * y). Каждое уравнение мощности требует нахождения натурального логарифма, умножения и возведения e в степень.

Как я упоминал в моем предыдущем ответе, только при степени 10 Math.Pow() становится быстрее, но точность будет снижена при использовании серии умножений.

0
ответ дан IamIC 8 March 2015 в 01:03
поделиться

Здесь обсуждается тема встроенного умножения против Math.pow

Очевидно, Math.pow медленнее, но не намного ...

1
ответ дан Demi 8 March 2015 в 01:03
поделиться

Давайте использовать соглашение x ^ n. Давайте предположим, что n всегда является целым числом.

При малых значениях n скучное умножение будет быстрее, потому что Math.Pow (вероятно, зависит от реализации) использует причудливые алгоритмы, позволяющие n быть нецелым и / или отрицательным.

Для больших значений n Math.Pow, скорее всего, будет быстрее, но если ваша библиотека не очень умная, она будет использовать тот же алгоритм, который не идеален, если вы знаете, что n всегда является целым числом. Для этого вы можете кодировать реализацию возведения в степень , возводя в квадрат или какой-нибудь другой причудливый алгоритм.

Конечно, современные компьютеры очень быстры, и вам, вероятно, следует придерживаться самого простого, легкочитаемого, наименее вероятного метода с ошибками, пока вы не сравните тест программы и не будете уверены, что вы получите значительное ускорение с помощью другого алгоритма.

2
ответ дан David 8 March 2015 в 01:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: