您好,登錄后才能下訂單哦!
本篇內容介紹了“Python比C++快嗎”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
眾所周知,Python 是動態(tài)語言,有全局解釋器鎖,比其他靜態(tài)語言要慢,也正是這個原因,你也許會轉向其他語言如 Java、C++,不過先等等,今天分享一個可以讓 Python 比 C++ 還要快的技術,看完再決定要不要轉吧。
今天的主角就是 Numba,Numba 是一個開源的即時編譯器(JIT compiler),可將 Python 和 NumPy 的代碼的轉換為快速的機器碼,從而提升運行速度。可以達到 C 或 FORTRAN 的速度。
這么牛逼是不是很難用呢?No,No,No,So easy,你不需要替換 Python 解釋器,不需要單獨編譯,甚至不需要安裝 C / C ++ 編譯器。只需將 Numba 提供的裝飾器放在 Python 函數(shù)上面就行,剩下的就交給 Numba 完成。舉個簡單的例子:
from numba import jit import random @jit(nopython=True) def monte_carlo_pi(nsamples): acc = 0 for i in range(nsamples): x = random.random() y = random.random() if (x ** 2 + y ** 2) < 1.0: acc += 1 return 4.0 * acc / nsamples
Numba 是專為科學計算而設計的,在與 NumPy 一起使用時,Numba 會為不同的數(shù)組數(shù)據(jù)類型生成專門的代碼,以優(yōu)化性能:
@numba.jit(nopython=True, parallel=True) def logistic_regression(Y, X, w, iterations): for i in range(iterations): w -= np.dot(((1.0 / (1.0 + np.exp(-Y * np.dot(X, w))) - 1.0) * Y), X) return w
現(xiàn)在我們來看看,同樣的代碼,使用 Numba 前后與 C++ 的性能對比。比如說我們要找出 1000 萬以內所有的素數(shù),代碼的算法邏輯是相同的: Python 代碼:
import math import time def is_prime(num): if num == 2: return True if num <= 1 or not num % 2: return False for div in range(3, int(math.sqrt(num) + 1), 2): if not num % div: return False return True def run_program(N): total = 0 for i in range(N): if is_prime(i): total += 1 return total if __name__ == "__main__": N = 10000000 start = time.time() total = run_program(N) end = time.time() print(f"total prime num is {total}") print(f"cost {end - start}s")
執(zhí)行耗時:
total prime num is 664579 cost 47.386465072631836s
C++ 代碼如下:
#include <iostream> #include <cmath> #include <time.h> using namespace std; bool isPrime(int num) { if (num == 2) return true; if (num <= 1 || num % 2 == 0) return false; double sqrt_num = sqrt(double(num)); for (int div = 3; div <= sqrt_num; div +=2){ if (num % div == 0) return false; } return true; } int run_program(int N){ int total = 0; for (int i; i < N; i++) { if(isPrime(i)) total ++; } return total; } int main() { int N = 10000000; clock_t start,end; start = clock(); int total = run_program(N); end = clock(); cout << "total prime num is " << total; cout << "\ncost " << (end - start) / ((double) CLOCKS_PER_SEC) << "s\n"; return 0; }
$ g++ isPrime.cpp -o isPrime $ ./isPrime total prime num is 664579 cost 2.36221s
c++
C++ 確實牛逼,才 2.3 秒,不過好戲還在后頭,現(xiàn)在我們使用 Numba 來加速一下,操作很簡單,不需要改動原有的代碼,先導入 Numba 的 njit,再在函數(shù)上方放個裝飾器 @njit 即可,其他保持不變,代碼如下:
import math import time from numba import njit # @njit 相當于 @jit(nopython=True) @njit def is_prime(num): if num == 2: return True if num <= 1 or not num % 2: return False for div in range(3, int(math.sqrt(num) + 1), 2): if not num % div: return False return True @njit def run_program(N): total = 0 for i in range(N): if is_prime(i): total += 1 return total if __name__ == "__main__": N = 10000000 start = time.time() total = run_program(N) end = time.time() print(f"total prime num is {total}") print(f"cost {end - start}s")
運行一下,可以看出時間已經(jīng)從 47.39 秒降低到 3 秒。
total prime num is 664579 cost 3.0948808193206787s
相比 C++ 的 2.3 秒還是有一點慢,你可能會說 Python 還是不行啊。等一等,我們還有優(yōu)化的空間,就是 Python 的 for 循環(huán),那可是 1000 萬的循環(huán),對此,Numba 提供了 prange 參數(shù)來并行計算,從而并發(fā)處理循環(huán)語句,只需要將 range 修改為 prange,裝飾器傳個參數(shù):parallel = True,其他不變,代碼改動如下:
import math import time from numba import njit, prange @njit def is_prime(num): if num == 2: return True if num <= 1 or not num % 2: return False for div in range(3, int(math.sqrt(num) + 1), 2): if not num % div: return False return True @njit(parallel = True) def run_program(N): total = 0 for i in prange(N): if is_prime(i): total += 1 return total if __name__ == "__main__": N = 10000000 start = time.time() total = run_program(N) end = time.time() print(f"total prime num is {total}") print(f"cost {end - start}s")
現(xiàn)在運行一下:
python isPrime.py total prime num is 664579 cost 1.4398791790008545s
才 1.43 秒,比 C++ 還快,Numba 真的牛逼!我又運行了兩次,確認自己沒看錯,平均就是 1.4 秒
“Python比C++快嗎”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網(wǎng)站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。