「 Pythonプログラミング:コンピュータサイエンス入門」からの引用
べき乗**を使用して平方根を取ることができます。math.sqrtを使用すると、いくらか効率的です。
「やや」ですが、どの程度、どのように?
「 Pythonプログラミング:コンピュータサイエンス入門」からの引用
べき乗**を使用して平方根を取ることができます。math.sqrtを使用すると、いくらか効率的です。
「やや」ですが、どの程度、どのように?
理論的には、hammarの答えとduffymoの答えは良い推測です。しかし実際には、私のマシンでは、それはより効率的ではありません。
>>> import timeit
>>> timeit.timeit(stmt='[n ** 0.5 for n in range(100)]', setup='import math', number=10000)
0.15518403053283691
>>> timeit.timeit(stmt='[math.sqrt(n) for n in range(100)]', setup='import math', number=10000)
0.17707490921020508
問題の一部は.
操作です。sqrt
名前空間に直接インポートすると、わずかに改善されます。
>>> timeit.timeit(stmt='[sqrt(n) for n in range(100)]', setup='from math import sqrt', number=10000)
0.15312695503234863
そこのキーワード:わずか。
さらなるテストは、数が大きくなるにつれて、使用することから得られる利益がsqrt
増加することを示しています。しかし、それでもそれほど多くはありません!
>>> timeit.timeit(stmt='[n ** 0.5 for n in range(1000000)]', setup='import math', number=1)
0.18888211250305176
>>> timeit.timeit(stmt='[math.sqrt(n) for n in range(1000000)]', setup='import math', number=1)
0.18425297737121582
>>> timeit.timeit(stmt='[sqrt(n) for n in range(1000000)]', setup='from math import sqrt', number=1)
0.1571958065032959
実装を推測する必要はありません。コードを読むことができます。
math.sqrt
sqrt
標準Cライブラリの薄いラッパーですmathmodule.c
。956行を参照してください。
演算子には、引数のタイプに応じて複数の**
実装がありますが、浮動小数点指数の場合、最終的にpow
は標準Cライブラリからディスパッチします(floatobject.c
783行目を参照)。
最近のCPUには、一般的なべき乗ルーチンでは使用されない特別な平方根命令が含まれていることがよくあります(たとえば、x86-64のglibcの実装との実装を比較対照します)pow
。sqrt
ただし、すべてのインタープリターオーバーヘッド(バイトコード、タイプチェック、メソッドディスパッチなど)が追加されると、生の速度の違いはそれほど重要ではなく、sqrt
直接呼び出すか、math
モジュール(他の回答のタイミングで示されているように)。
**
math.sqrt
常にであることを知っている間、指数をサポートする必要があり0.5
ます。math.sqrt
したがって、より特殊な(したがっておそらくより効率的な)アルゴリズムを使用できます。
私の推測では、math.sqrtは2乗に収束するニュートン法を使用し、べき乗はより遅い他の方法を使用します。
これは少し異なるアプローチです。平方根より少し大きいintが必要です。2つの方法(平方数には同意しませんが、それで問題ありません):
>>>timeit.timeit(stmt='[int(n**0.5)+1 for n in range(1000000)]', setup='', number=1)
0.481772899628
>>>timeit.timeit(stmt='[ceil(sqrt(n)) for n in range(1000000)]', setup='from math import sqrt, ceil', number=1)
0.293844938278
>>>timeit.timeit(stmt='[int(ceil(sqrt(n))) for n in range(1000000)]', setup='from math import sqrt, ceil', number=1)
0.511347055435
したがって、数学関数はより高速です...floatをintに変換するまで。(値と多くの比較を行う必要があります。テストはしていませんが、整数の比較は浮動小数点数の比較よりも安価であるはずです。)
しかしねえ、それはPythonです。このレベルの粒度でパフォーマンスを最適化しようとするには、抽象化が多すぎます。