<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 速度慢,試試這個方法提高 1000 倍

          共 4840字,需瀏覽 10分鐘

           ·

          2021-05-19 20:40

          ????關注后回復 “進群” ,拉你進程序員交流群????

          作者 | Andrew Zhu

          譯者 | 蘇本如

          出品 | CSDN(ID:CSDNnews)


          1、人們一直詬病 Python 程序的速度很慢,它到底有多慢呢?


          在每次的編程語言速度競賽中,Python 的名次通常都比較墊底。有人解釋這是因為 Python 是一種解釋型語言(代碼無需編譯即可執(zhí)行),而所有的解釋型編程語言執(zhí)行速度都很慢。然而,我們知道 Java 也是一種解釋型語言,它的字節(jié)碼是由 JVM 解釋的。而在這個基準測試速度比較頁面上的結果卻顯示:Java 要比 Python 的速度快得多。

          下面是一個可以用來演示 Python 速度慢的示例。它使用傳統(tǒng)的 for 循環(huán)來產生一個數(shù)的倒數(shù):

          import numpy as np
          np.random.seed(0)
          values = np.random.randint(1, 100, size=1000000)
          def get_reciprocal(values):
          output = np.empty(len(values))
          for i in range(len(values)):
          output[i] = 1.0/values[i]
          %timeit get_reciprocal(values)

          結果顯示:

          每個循環(huán)平均耗時3.37秒(標準偏差±582毫秒)(共計運行了7次程序,每次一個循環(huán))

          計算 1,000,000 個倒數(shù)竟然需要 3.37 秒。使用 C 語言執(zhí)行同樣的運算只需要不到一眨眼的工夫:9 毫秒;C# 需要 19 毫秒;Nodejs 需要 26 毫秒;Java 僅僅需要 5 毫秒!而 Python 竟然用了讓人懷疑人生的 3.37秒(它到底做了些什么)?。ㄗⅲ涸诒疚牡淖詈螅腋缴狭怂姓Z言的測試代碼)。



          2、Python 速度緩慢的根本原因


          我們通常把 Python 稱為一種動態(tài)類型編程語言。而 Python 程序中的一切變量都是以對象的形式存在,換句話說,每次 Python 代碼處理數(shù)據(jù)時,都需要進行對象拆箱操作,以確定對象的具體類型。在 for 循環(huán)內部,每次循環(huán)都需要拆箱對象,檢查類型并計算倒數(shù)。那3秒鐘的時間都在類型檢查中浪費了。

          C 語言和其他傳統(tǒng)的編程語言則不同,它們對數(shù)據(jù)的訪問是直接的。但在 Python 中,大量的 CPU 時間都用在了類型檢查上。

          即使是一個簡單的賦值操作也會花費很長的時間。如:

          a = 1

          這個簡單的賦值操作,它需要如下兩個步驟:

          • 步驟 1:將 a->PyObject_HEAD->typecode 設置為 Integer 類型.

          • 步驟 2. 將值 1 賦值 a (a->val =1).

          關于 Python 為什么速度慢的更多信息,Jake 寫的這篇精彩文章值得一讀:Why Python is Slow: Looking Under the Hood

          那么,有沒有一種方法可以繞過類型檢查,從而提高 Python 程序的性能呢?



          3、答案是:使用 NumPy 通用函數(shù)


          與 Python 列表(list)不同,NumPy 數(shù)組是圍繞 C 數(shù)組構建的對象。NumPy 數(shù)組訪問項不需要任何步驟來檢查類型。這給我們找到解決方案指明了方向:使用 NumPy 通用函數(shù)(亦即UFunc)。

          簡而言之,UFunc 是一種可以直接對整個數(shù)組進行算術運算的方法。下面我們將前面那個慢速的 Python 示例改寫為 UFunc 版本,它就像下面這樣:

          import numpy as np
          np.random.seed(0)
          values = np.random.randint(1, 100, size=1000000)
          %timeit result = 1.0/values

          改寫后的代碼不僅提高了速度,而且代碼變得更短。猜猜現(xiàn)在這個程序執(zhí)行要花多少時間?它比我上面提到的最快的語言快了2.7毫秒

          每個循環(huán)平均耗時2.71毫秒(標準偏差±50.8微秒)(共運行了7次程序,每次循環(huán)100個)

          返回代碼,關鍵是 1.0/values 這一行。這里的 values 不是一個數(shù)字,而是一個 NumPy 數(shù)組。和除法運算符一樣,Numpy 還有許多其他運算符(如下圖示)。

          點擊這里可以找到所有 Ufunc 運算(操作)符。



          4、總結


          對于那些使用 Python 的人來說,使用 Python 處理數(shù)據(jù)和數(shù)字的可能性很大。這些數(shù)據(jù)可以存儲在 NumPy 或 Pandas DataFrame中,因為DataFrame 是基于 NumPy 實現(xiàn)的。所以 Ufunc 也可以使用。

          UFunc 使我們能夠以超越幾個數(shù)量級的更快速度在 Python 中執(zhí)行重復操作。最慢的 Python 甚至可以跑得 C 語言更快。這一點太讓人激動了。



          5、附錄— C,C#,Java 和 NodeJS 的測試代碼


          C 語言:

          #include <stdio.h>
          #include <stdlib.h>
          #include <sys/time.h>

          int main(){
          struct timeval stop, start;
          int length = 1000000;
          int rand_array[length];
          float output_array[length];
          for(int i = 0; i<length; i++){
          rand_array[i] = rand();
          }
          gettimeofday(&start, NULL);
          for(int i = 0; i<length; i++){
          output_array[i] = 1.0/(rand_array[i]*1.0);
          }
          gettimeofday(&stop, NULL);
          printf("took %lu us\n", (stop.tv_sec - start.tv_sec) * 1000000 + stop.tv_usec - start.tv_usec);
          printf("done\n");
          return 0;
          }

          C#(.net 5.0):

          using System;
          namespace speed_test{
          class Program{
          static void Main(string[] args){
          int length = 1000000;
          double[] rand_array =new double[length];
          double[] output = new double[length];
          var rand = new Random();
          for(int i =0; i<length;i++){
          rand_array[i] = rand.Next();
          //Console.WriteLine(rand_array[i]);
          }
          long start = DateTimeOffset.Now.ToUnixTimeMilliseconds();
          for(int i =0;i<length;i++){
          output[i] = 1.0/rand_array[i];
          }
          long end = DateTimeOffset.Now.ToUnixTimeMilliseconds();
          Console.WriteLine(end - start);
          }
          }
          }

          Java:

          import java.util.Random;

          public class speed_test {
          public static void main(String[] args){
          int length = 1000000;
          long[] rand_array = new long[length];
          double[] output = new double[length];
          Random rand = new Random ();
          for(int i =0; i<length; i++){
          rand_array[i] = rand.nextLong();
          }
          long start = System.currentTimeMillis();
          for(int i = 0;i<length; i++){
          output[i] = 1.0/rand_array[i];
          }
          long end = System.currentTimeMillis();
          System.out.println(end - start);
          }
          }

          NodeJS:

          let length = 1000000;
          let rand_array = [];
          let output = [];
          for(var i=0;i<length;i++){
          rand_array[i] = Math.floor(Math.random()*10000000);
          }
          let start = (new Date()).getMilliseconds();
          for(var i=0;i<length;i++){
          output[i] = 1.0/rand_array[i];
          }
          let end = (new Date()).getMilliseconds();
          console.log(end - start);

          原文鏈接:

          https://python.plainenglish.io/a-solution-to-boost-python-speed-1000x-times-c9e7d5be2f40

          -End-

          最近有一些小伙伴,讓我?guī)兔φ乙恍?nbsp;面試題 資料,于是我翻遍了收藏的 5T 資料后,匯總整理出來,可以說是程序員面試必備!所有資料都整理到網(wǎng)盤了,歡迎下載!

          點擊??卡片,關注后回復【面試題】即可獲取

          在看點這里好文分享給更多人↓↓

          瀏覽 33
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  精品国内视频 | 91亚洲精品久久久久久久久久久久 | 免费毛片大全 | 中文字幕无码高清的A V不卡的A V | 免费高清无码在线观看 |