<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python可以比C++更快,你不信?

          共 9544字,需瀏覽 20分鐘

           ·

          2021-04-12 22:20

          ↑↑↑關(guān)注后"星標"簡說Python

          人人都可以簡單入門Python、爬蟲、數(shù)據(jù)分析
           簡說Python推薦 
          來源:Python七號
          作者:somenzz

          大家好,我是老表,Python 是一個用途非常廣泛的編程語言,擁有成千上萬的第三方庫,在人工智能、機器學(xué)習(xí)、自動化等方面有著廣泛的應(yīng)用,眾所周知,Python 是動態(tài)語言,有全局解釋器鎖,比其他靜態(tài)語言要慢,也正是這個原因,你也許會轉(zhuǎn)向其他語言如 Java、C++,不過先等等,今天分享一個可以讓 Python 比 C++ 還要快的技術(shù),看完再決定要不要轉(zhuǎn)吧。

          今天的主角就是 Numba,Numba 是一個開源的即時編譯器(JIT compiler),可將 Python 和 NumPy 的代碼的轉(zhuǎn)換為快速的機器碼,從而提升運行速度。可以達到 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 是專為科學(xué)計算而設(shè)計的,在與 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 萬以內(nèi)所有的素數(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 == 2return true;
              if (num <= 1 || num % 2 == 0return false;
              double sqrt_num = sqrt(double(num));
              for (int div = 3; div <= sqrt_num; div +=2){
                 if (num % div == 0return 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 來加速一下,操作很簡單,不需要改動原有的代碼,先導(dǎo)入 Numba 的 njit,再在函數(shù)上方放個裝飾器 @njit 即可,其他保持不變,代碼如下:

          import math
          import time
          from numba import njit

          # @njit 相當(dāng)于 @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

          看到這里,Numba 又讓我燃起了對 Python 的激情,我不轉(zhuǎn) C++ 了,Python 夠用了。

          Numba 如何做到的呢?官方文檔這樣介紹:它讀取裝飾函數(shù)的 Python 字節(jié)碼,并將其與有關(guān)函數(shù)輸入?yún)?shù)類型的信息結(jié)合起來,分析和優(yōu)化代碼,最后使用編譯器庫(LLVM)針對你的 CPU 生成量身定制的機器代碼。每次調(diào)用函數(shù)時,都會使用此編譯版本,你說牛逼不?

          Numba 還有更多詳細的用法,這里不多說,想了解的請移步官方文檔[1]

          最后的話

          Python 幾乎在每一個領(lǐng)域都有對應(yīng)的解決方案,本文提到的 Numba 庫就是專門解決 Python 在計算密集型任務(wù)方面性能不足的問題,如果你從事機器學(xué)習(xí)、數(shù)據(jù)挖掘等領(lǐng)域,這個會非常有幫助,如果本文對你有用,請點贊、在看、關(guān)注支持。

          參考資料

          [1]

          官方文檔: https://numba.readthedocs.io/

          最后給大家分享《100本Python電子書》,包括Python編程技巧、數(shù)據(jù)分析、爬蟲、Web開發(fā)、機器學(xué)習(xí)、深度學(xué)習(xí)。
          現(xiàn)在免費分享出來,有需要的讀者可以下載學(xué)習(xí),在下面的公眾號「程序員獅子里回復(fù)關(guān)鍵字Python,就行
          -END-

          文末推薦一本《R語言數(shù)據(jù)分析與可視化從入門到精通》R語言是一個自由、免費、源代碼開放的編程語言和環(huán)境,它提供了強大的數(shù)據(jù)分析功能和豐富的數(shù)據(jù)可視化手段。隨著數(shù)據(jù)科學(xué)的快速發(fā)展,R語言已經(jīng)成為數(shù)據(jù)分析領(lǐng)域炙手可熱的通用語言。全書分為3篇共12章。


          掃下方二維碼添加我的私人微信,可以在我的朋友圈獲取最新的Python學(xué)習(xí)資料,以及近期推文中的源碼或者其他資源,另外不定期開放學(xué)習(xí)交流群,以及朋友圈福利(送書、紅包、學(xué)習(xí)資源等)。

          掃碼查看我朋友圈

          獲取最新學(xué)習(xí)資源


          學(xué)習(xí)更多:
          整理了我開始分享學(xué)習(xí)筆記到現(xiàn)在超過250篇優(yōu)質(zhì)文章,涵蓋數(shù)據(jù)分析、爬蟲、機器學(xué)習(xí)等方面,別再說不知道該從哪開始,實戰(zhàn)哪里找了

          點贊”傳統(tǒng)美德不能丟 

          瀏覽 98
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄页网站视频 | 免费看日本一级片 | 国产无码免费在线观看 | aaa一级电影网站 | 97Av电影手机版 |