C++において,平方根計算の際に,一般的に数学関数(<cmath>ヘッダ)を使用します.
平方根の算出には,専用関数std::sqrt(x)
とべき乗関数std::pow(x,0.5e0)
を使用する方法が考えられます.
この記事では,std::sqrt
とstd::pow
による平方根算出の速度比較しました.
平方根の計算でstd::sqrt
とstd::pow
どちらを使うべき?
専用関数であるstd::sqrt
を使おう!
↓↓↓立方根(三乗根)に関する速度比較した記事はこちら↓↓↓
目次
検証
結果
最適化なし(-O0)
std::sqrt
はstd::pow
の約11倍高速な結果となりました.
最適化あり(-O2)
最適化を行った場合,std::sqrt
はstd::pow
の約23倍高速な結果となりました.
検証に使用したコード
速度検証のため,Google Benchmarkを使用しました.
Google Benchmarkに関しては別記事にしています.下記記事をご覧ください.
C++でのベンチマークテストのためにGoogle Benchmarkライブラリを利用する
便利なベンチマークツールは使うべし! 単体テストは重要性は近年では広く周知されています.一方で,性能に関してはなかなか議論されることが多くありません. その一…
検証に使用したコードは下記のようになります.
#include <benchmark/benchmark.h>
#include <cmath>
#include <iostream>
#include <random>
static void plus(benchmark::State& state)
{
std::random_device seed;
std::mt19937 rng(seed());
std::uniform_real_distribution<> distr(-M_PI_2, M_PI_2);
double sum = 0.0e0;
for (auto _ : state)
{
sum += distr(rng);
}
// prevent ignore code by optimization
std::cout << sum << std::endl;
}
BENCHMARK(plus);
static void sqrt(benchmark::State& state)
{
std::random_device seed;
std::mt19937 rng(seed());
std::uniform_real_distribution<> distr(0.0e0, 1000.0e0);
double sum = 0.0e0;
for (auto _ : state)
{
sum += std::sqrt(distr(rng));
}
// prevent ignore code by optimization
std::cout << sum << std::endl;
}
BENCHMARK(sqrt);
static void pow_sqrt(benchmark::State& state)
{
std::random_device seed;
std::mt19937 rng(seed());
std::uniform_real_distribution<> distr(0.0e0, 1000.0e0);
double sum = 0.0e0;
for (auto _ : state)
{
sum += std::pow(distr(rng), 0.5e0);
}
// prevent ignore code by optimization
std::cout << sum << std::endl;
}
BENCHMARK(pow_sqrt);
BENCHMARK_MAIN();
検証結果において乱数生成と加算の計算時間は,別途減算しています.
結論
std::sqrt
とstd::pow
の平方根算出速度には有意な差がありました.
平方根算出のための関数であるstd::sqrt
の方が高速であることが示さされました.
基本的にstd::sqrt
を使用したほうが良いでしょう.
↓↓↓立方根(三乗根)に関する速度比較した記事はこちら↓↓↓
リンク