ホームページ  >  記事  >  バックエンド開発  >  べき乗には `pow(x, i)` の代わりに `x*x...` を使用する方が常に速いのでしょうか?

べき乗には `pow(x, i)` の代わりに `x*x...` を使用する方が常に速いのでしょうか?

Patricia Arquette
Patricia Arquetteオリジナル
2024-11-12 06:53:02516ブラウズ

Is it always faster to use `x*x...` instead of `pow(x, i)` for exponentiation?

べき乗手法の効率の決定

多くの場合、べき乗専用の関数を使用する代わりに数値を単独で乗算する方が効率的です。 pow() のように。ただし、特に特定の指数の場合、この規則には例外がある可能性があります。

xx... と pow(x,i) のパフォーマンスをテストするには、次のコードを検討してください。 exponents 'i':

#include <cstdlib>
#include <cmath>
#include <boost/date_time/posix_time/posix_time.hpp>

inline boost::posix_time::ptime now()
{
    return boost::posix_time::microsec_clock::local_time();
}

#define TEST(num, expression) \
double test##num(double b, long loops) \
{ \
    double x = 0.0; \
    boost::posix_time::ptime startTime = now(); \
    for (long i=0; i<loops; ++i) \
    { \
        x += expression; \
        x += expression; \
        x += expression; \
        x += expression; \
        x += expression; \
        x += expression; \
        x += expression; \
        x += expression; \
        x += expression; \
        x += expression; \
    } \
    boost::posix_time::time_duration elapsed = now() - startTime; \
    std::cout << elapsed << " "; \
    return x; \
}

// Test cases for exponentiation using x*x...
TEST(1, b)
TEST(2, b*b)
TEST(3, b*b*b)
TEST(4, b*b*b*b)
TEST(5, b*b*b*b*b)

// Test cases for exponentiation using pow()
template <int exponent>
double testpow(double base, long loops)
{
    double x = 0.0;
    boost::posix_time::ptime startTime = now();
    for (long i = 0; i < loops; ++i)
    {
        x += std::pow(base, exponent);
        x += std::pow(base, exponent);
        x += std::pow(base, exponent);
        x += std::pow(base, exponent);
        x += std::pow(base, exponent);
        x += std::pow(base, exponent);
        x += std::pow(base, exponent);
        x += std::pow(base, exponent);
        x += std::pow(base, exponent);
        x += std::pow(base, exponent);
    }
    boost::posix_time::time_duration elapsed = now() - startTime;
    std::cout << elapsed << " ";
    return x;
}

int main()
{
    long loops = 100000000l;
    double x = 0.0;
    std::cout << "1 ";
    x += testpow<1>(rand(), loops);
    x += test1(rand(), loops);

    std::cout << "\n2 ";
    x += testpow<2>(rand(), loops);
    x += test2(rand(), loops);

    std::cout << "\n3 ";
    x += testpow<3>(rand(), loops);
    x += test3(rand(), loops);

    std::cout << "\n4 ";
    x += testpow<4>(rand(), loops);
    x += test4(rand(), loops);

    std::cout << "\n5 ";
    x += testpow<5>(rand(), loops);
    x += test5(rand(), loops);
    std::cout << "\n" << x << "\n";
}

結果

各べき乗法にかかる時間を測定するテスト結果は、xx... 確かに高速です。

ただし、特定の例外があります

pow(x, 3) に関しては、コンパイラと最適化によって結果が異なる場合があります特に「double」などの浮動小数点変数を使用する場合はフラグを使用します。

特定の状況では、x

xx*... は必ずしも pow(x, 3) より高速であるとは限りません。いくつかの報告されたベンチマークで観察されました。これは、最新のコンパイラで採用されている最適化手法によるものです。

結論

while x

x... のような小さい指数値では、一般に高速なままです。 1、2、または 3 のいずれであっても、コードに対して最も効率的なアプローチを決定する際には、特定の実装の詳細とコンパイラの最適化を考慮することが重要です。

以上がべき乗には `pow(x, i)` の代わりに `x*x...` を使用する方が常に速いのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。