Saya sudah lama bertanya-tanya tentang hal ini. Seperti judulnya, mana yang lebih cepat, fungsi sebenarnya atau hanya menaikkan setengah daya?
MEMPERBARUI
Ini bukan masalah optimasi prematur. Ini hanyalah pertanyaan tentang bagaimana sebenarnya kode yang mendasarinya bekerja. Apa teori tentang bagaimana kode Python bekerja?
Saya mengirim Guido van Rossum email sebab saya benar-benar ingin tahu perbedaan dalam metode ini.
Email saya:
Setidaknya ada 3 cara untuk melakukan root kuadrat dalam Python: math.sqrt, operator '**' dan pow (x, .5). Saya hanya ingin tahu perbedaan dalam implementasi masing-masing. Dalam hal efisiensi, mana yang lebih baik?
Jawabannya:
pow dan ** adalah setara; math.sqrt tidak berfungsi untuk bilangan kompleks, dan tautan ke fungsi C sqrt (). Yang mana yang lebih cepat, saya tidak tahu ...
sumber
math.sqrt
rutin lebih dioptimalkan (sebagaimana adanya) dan mengekspresikan maksud lebih jelas, itu harus selalu lebih disukaix**.5
. Ini bukan optimasi dini untuk mengetahui apa yang Anda tulis, dan memilih alternatif yang lebih cepat dan memberikan kejelasan kode yang lebih banyak. Jika demikian, Anda perlu berdebat dengan baik mengapa Anda memilih alternatif lain.Jawaban:
math.sqrt(x)
secara signifikan lebih cepat daripadax**0.5
.Menggunakan Python 3.6.9 ( notebook ).
sumber
Berikut ini beberapa timing (Python 2.5.2, Windows):
Tes ini menunjukkan bahwa
x**.5
sedikit lebih cepat daripadasqrt(x)
.Untuk Python 3.0 hasilnya sebaliknya:
math.sqrt(x)
selalu lebih cepat daripadax**.5
di komputer lain (Ubuntu, Python 2.6 dan 3.1):sumber
Berapa banyak akar kuadrat yang benar-benar Anda lakukan? Apakah Anda mencoba menulis beberapa mesin grafis 3D dengan Python? Jika tidak, lalu mengapa menggunakan kode yang cryptic over code yang mudah dibaca? Perbedaan waktu adalah lebih sedikit daripada yang dapat dilihat siapa pun di hampir semua aplikasi yang dapat saya lihat. Saya benar-benar tidak bermaksud untuk meletakkan pertanyaan Anda, tetapi tampaknya Anda terlalu jauh dengan optimasi prematur.
sumber
Dalam benchmark mikro ini,
math.sqrt
akan lebih lambat, karena sedikit waktu yang dibutuhkan untuk mencarisqrt
dalam namespace matematika. Anda dapat sedikit meningkatkannya denganMeski begitu, menjalankan beberapa variasi melalui timeit, menunjukkan sedikit keuntungan kinerja (4-5%) untuk
x**.5
Menariknya, lakukan
mempercepatnya bahkan lebih, hingga perbedaan kecepatan 1%, dengan signifikansi statistik yang sangat sedikit.
Saya akan mengulangi Kibbee, dan mengatakan bahwa ini mungkin optimasi prematur.
sumber
Dalam python 2.6
(float).__pow__()
fungsi menggunakanpow()
fungsi C danmath.sqrt()
fungsi menggunakan Csqrt()
fungsiDalam glibc compiler implementasinya
pow(x,y)
cukup kompleks dan dioptimalkan dengan baik untuk berbagai kasus luar biasa. Misalnya, memanggil Cpow(x,0.5)
cukup memanggilsqrt()
fungsi.Perbedaan kecepatan penggunaan
.**
ataumath.sqrt
disebabkan oleh pembungkus yang digunakan di sekitar fungsi C dan kecepatan sangat tergantung pada flag optimasi / kompiler C yang digunakan pada sistem.Edit:
Ini adalah hasil algoritma Claudiu di komputer saya. Saya mendapat hasil berbeda:
sumber
Untuk apa nilainya (lihat jawaban Jim). Di mesin saya, menjalankan python 2.5:
sumber
menggunakan kode Claudiu, di komputer saya bahkan dengan "dari impor matematika sqrt" x **. 5 lebih cepat tetapi menggunakan psyco.full () sqrt (x) menjadi jauh lebih cepat, setidaknya 200%
sumber
Kemungkinan besar math.sqrt (x), karena dioptimalkan untuk rooting persegi.
Tingkatan yang dicapai akan memberi Anda jawaban yang Anda cari.
sumber
Seseorang berkomentar tentang "akar kuadrat cepat Newton-Raphson" dari Quake 3 ... Saya menerapkannya dengan ctypes, tetapi sangat lambat dibandingkan dengan versi asli. Saya akan mencoba beberapa optimasi dan implementasi alternatif.
Berikut metode lain menggunakan struct, keluar sekitar 3.6x lebih cepat dari versi ctypes, tetapi masih 1/10 kecepatan C.
sumber
Hasil Claudiu berbeda dari saya. Saya menggunakan Python 2.6 di Ubuntu pada mesin P4 2.4Ghz lama ... Inilah hasil saya:
sqrt secara konsisten lebih cepat bagi saya ... Bahkan Codepad.org SEKARANG tampaknya setuju bahwa sqrt, dalam konteks lokal, lebih cepat ( http://codepad.org/6trzcM3j ). Codepad tampaknya sedang menjalankan Python 2.5 saat ini. Mungkin mereka menggunakan 2.4 atau lebih tua ketika Claudiu pertama kali menjawab?
Bahkan, bahkan menggunakan math.sqrt (i) sebagai pengganti arg (i), saya masih mendapatkan waktu yang lebih baik untuk sqrt. Dalam hal ini timeit2 () mengambil antara 0,53 dan 0,55 detik pada mesin saya, yang masih lebih baik daripada angka 0,56-0,60 dari timeit1.
Saya akan mengatakan, pada Python modern, gunakan math.sqrt dan jelas membawanya ke konteks lokal, baik dengan somevar = math.sqrt atau dengan dari impor matematika sqrt.
sumber
Hal Pythonic untuk dioptimalkan adalah keterbacaan. Untuk ini saya pikir penggunaan eksplisit dari
sqrt
fungsi adalah yang terbaik. Karena itu, mari kita selidiki kinerja.Saya memperbarui kode Claudiu untuk Python 3 dan juga membuatnya tidak mungkin untuk mengoptimalkan perhitungan (sesuatu yang dapat dilakukan oleh kompiler Python yang baik di masa depan):
Hasil bervariasi, tetapi output sampel adalah:
Cobalah sendiri.
sumber
Masalah SQRMINSUM yang telah saya pecahkan baru-baru ini membutuhkan komputasi akar kuadrat berulang kali pada dataset besar. 2 kiriman tertua dalam sejarah saya , sebelum saya membuat pengoptimalan lainnya, berbeda hanya dengan mengganti ** 0,5 dengan sqrt (), sehingga mengurangi runtime dari 3,74s menjadi 0,51s di PyPy. Ini hampir dua kali lipat peningkatan 400% yang sudah besar yang diukur Claudiu.
sumber
Tentu saja, jika seseorang berhadapan dengan literal dan membutuhkan nilai konstan, runtime Python dapat pra-menghitung nilai pada waktu kompilasi, jika ditulis dengan operator - tidak perlu membuat profil setiap versi dalam kasus ini:
sumber
Apa yang akan lebih cepat adalah jika Anda masuk ke math.py dan menyalin fungsi "sqrt" ke program Anda. Program Anda membutuhkan waktu untuk menemukan math.py, lalu membukanya, menemukan fungsi yang Anda cari, dan kemudian mengembalikannya ke program Anda. Jika fungsi itu lebih cepat bahkan dengan langkah-langkah "pencarian", maka fungsi itu sendiri harus sangat cepat. Mungkin akan memotong waktu Anda menjadi dua. Singkatnya:
sumber
from math import sqrt
?