Лучшие практики с Math.Pow

Я работаю над библиотекой обработки изображений, которая расширяет OpenCV, HALCON, .... Библиотека должна быть с .NET Framework 3.5, и, поскольку мой опыт работы с .NET ограничен, я хотел бы задать несколько вопросов относительно производительности.

Я столкнулся с некоторыми конкретными вещами, которые я не могу объяснить себе должным образом, и хотел бы, чтобы вы спросили: а) почему и б) как лучше всего разобраться в этих случаях.

Мой первый вопрос касается математики. пау. Я уже нашел здесь несколько ответов на StackOverflow, которые довольно хорошо объясняют это (а), но не то, что с этим делать (б). Моя программа тестирования выглядит так

Stopwatch watch = new Stopwatch();  // from the Diagnostics class
watch.Start();
for (int i = 0; i < 1000000; i++)
    double result = Math.Pow(4,7)   // the function call
watch.Stop()

Результат был не очень хорошим (~ 300 мс на моем компьютере) (я запускал тест 10 раз и вычислял среднее значение).

Моя первая идея заключалась в том, чтобы проверить, так ли это потому, что это статическая функция. Итак, я реализовал свой собственный класс

class MyMath
{
    public static double Pow (double x, double y)   //Using some expensive functions to calculate the power
    {
        return Math.Exp(Math.Log(x) * y);
    }

    public static double PowLoop (double x, int y)  // Using Loop
    {
        double res = x;
        for(int i = 1; i < y; i++)
            res *= x;
        return res;
    }

    public static double Pow7 (double x)            // Using inline calls
    {
        return x * x * x * x * x * x * x;
    }
}

. Третье, что я проверил, заключалось в том, заменю ли я Math.Pow (4,7) непосредственно на 4 * 4 * 4 * 4 * 4 * 4 * 4.

Результат (среднее значение из 10 тестовых прогонов)

300 ms   Math.Pow(4,7)
356 ms   MyMath.Pow(4,7)    //gives wrong rounded results
264 ms   MyMath.PowLoop(4,7)
 92 ms   MyMath.Pow7(4)
 16 ms   4*4*4*4*4*4*4

Теперь моя ситуация в основном такая: не используйте математику для Pow. Моя единственная проблема в том, что ... действительно ли мне нужно сейчас реализовать свой собственный математический класс? Кажется неэффективным реализовать собственный класс только для степенной функции. (Между прочим. PowLoop и Pow7 даже быстрее в сборке Release примерно на 25%, в то время как Math.Pow - нет.)

Мои последние вопросы:

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

б) если у вас есть код для оптимизации, действительно ли вы пишете все такие математические операции напрямую?

в) может быть, уже есть более быстрый ( open-source ^^) библиотека для математических операций

d) источник моего вопроса в основном таков: я предположил, что. NET Framework сама по себе уже предоставляет очень оптимизированные результаты кода / компиляции для таких базовых операций - будь то Math-Class или обработка массивов, и я был немного удивлен, сколько преимуществ я получу, написав свой собственный код. Есть ли какие-то другие общие "поля" или что-то еще, на что следует обратить внимание в C #, где я не могу напрямую доверять C #.

7
задан Cœur 13 December 2017 в 05:05
поделиться