<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倍的解決方案

          共 4171字,需瀏覽 9分鐘

           ·

          2021-04-06 23:46

          人們說(shuō)Python很慢,可能會(huì)很慢

          每當(dāng)出現(xiàn)編程速度競(jìng)賽時(shí),Python通常都會(huì)走到最底層。有人說(shuō)這是因?yàn)镻ython是一種解釋語(yǔ)言。所有的解釋語(yǔ)言都很慢。但是我們知道Java也是一種語(yǔ)言,它的字節(jié)碼由JVM解釋。

          https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/python3-java.html

          如本基準(zhǔn)測(cè)試所示,Java比Python快得多。

          這是一個(gè)可以演示Python慢度的示例。使用傳統(tǒng)的for循環(huán)產(chǎn)生倒數(shù):

          import numpy as npnp.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)

          結(jié)果:

          每個(gè)循環(huán)3.37 s±582毫秒(平均±標(biāo)準(zhǔn)偏差,共7次運(yùn)行,每個(gè)循環(huán)1次)

          神圣的xxx,計(jì)算1,000,000個(gè)倒數(shù)需要3.37s。C語(yǔ)言中的相同邏輯只需要眨一下就可以了:9ms ; C#需要19毫秒; Nodejs花費(fèi)26ms ; Java需要5毫秒!而Python則采用了自我懷疑的3.37秒。(我在最后附加了所有測(cè)試代碼)。

          緩慢的根本原因

          我們通常將Python稱為動(dòng)態(tài)類型編程語(yǔ)言。而且Python程序中的所有內(nèi)容都是object,換句話說(shuō),每次Python代碼處理數(shù)據(jù)時(shí),都需要將對(duì)象包裝拆箱。在for循環(huán)內(nèi)部,每次迭代都需要拆箱對(duì)象,檢查類型并計(jì)算倒數(shù)。那3秒鐘都在類型檢查中浪費(fèi)了

          與C之類的傳統(tǒng)語(yǔ)言不同,對(duì)數(shù)據(jù)的訪問(wèn)是直接的,而在Python中,大量的CPU周期用于檢查類型。

          即使是簡(jiǎn)單的數(shù)字分配也將花費(fèi)很長(zhǎng)時(shí)間。

          a = 1步驟1.設(shè)置a->PyObject_HEAD->typecode為整數(shù)步驟2.設(shè)置a->val =1
          那么,有沒(méi)有一種方法可以解決類型檢查,從而提高性能呢?

          解決方案:NumPy通用函數(shù)

          與Python列表不同,NumPy數(shù)組是圍繞C數(shù)組構(gòu)建的對(duì)象。NumPy中的訪問(wèn)項(xiàng)無(wú)需任何步驟即可檢查類型。這使我們了解了解決方案,它是NumPy通用函數(shù)(又稱UFunc)

          簡(jiǎn)而言之,UFunc是一種我們可以直接對(duì)整個(gè)數(shù)組進(jìn)行算術(shù)運(yùn)算的方法。將第一個(gè)慢速Python示例轉(zhuǎn)換為UFunc版本,它將像這樣:

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

          此代碼不僅可以提高速度,還可以縮短代碼長(zhǎng)度。猜猜現(xiàn)在需要多少時(shí)間?比我上面提到的任何其他語(yǔ)言快2.7ms

          每個(gè)循環(huán)2.71 ms±50.8 μs(平均±標(biāo)準(zhǔn)偏差,共運(yùn)行7次,每個(gè)循環(huán)100個(gè))
          返回代碼,關(guān)鍵是1.0/values這里是不是一個(gè)數(shù)字,它是一個(gè)NumPy的陣列。像除法運(yùn)算符一樣,還有很多其他運(yùn)算符。

          檢查這里的所有Ufunc運(yùn)營(yíng)商。

          對(duì)于那些使用Python的人,您很有可能使用Python處理數(shù)據(jù)和數(shù)字。這些數(shù)據(jù)可以存儲(chǔ)在NumPy或Pandas DataFrame中,因?yàn)镈ataFrame是基于NumPy實(shí)現(xiàn)的。因此,Ufunc也可以。

          UFunc使我們能夠在Python中以數(shù)量級(jí)更快的速度執(zhí)行重復(fù)操作。最慢的Python甚至可以比C語(yǔ)言更快。太棒了。

          附錄— C,C#,Java和NodeJS的測(cè)試代碼

          C語(yǔ)言:

          #include <stdio.h>#include <stdlib.h>#include <sys/time.h>
          int main(){ struct timeval stop, start; gettimeofday(&start, NULL); int length = 1000000; int rand_array[length]; float output_array[length]; for(int i = 0; i<length; i++){ rand_array[i] = rand(); } 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#(dotnet 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);

          往期推薦



          滲透測(cè)試員必備!Top 10免費(fèi)黑客工具

          手把手教你用Scrapy+Gerapy部署網(wǎng)絡(luò)爬蟲(chóng)

          這是我見(jiàn)過(guò)最有用的Mysql面試題,面試了無(wú)數(shù)公司總結(jié)的(內(nèi)附答案)

          面試穩(wěn)了!集齊幾千名程序員精選的 100 道性能面試題!

          刷完500道高頻面試題,我能去面試大廠了嗎?(持續(xù)更新)

          SeleniumWebDriver運(yùn)行數(shù)據(jù)庫(kù)測(cè)試?

          Selenium Webdriver上傳文件,別傻傻的分不清得3種方法

          如何將功能測(cè)試用例轉(zhuǎn)為自動(dòng)化腳本?

          微軟開(kāi)源最強(qiáng)自動(dòng)化工具-Playwright

          如何使用Selenium WebDriver查找錯(cuò)誤的鏈接?


          瀏覽 50
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  国产成人精品免费视频麻豆大全 | 影音先锋女人av鲁色资源久久 | 久久久久国产一区二区三区潘金莲 | 无码人妻精品一区二区蜜桃网站文 | 天天操天天操天天逼天天逼天天日天天逼 |