Python 是數(shù)據(jù)科學(xué) (DS) 和機(jī)器學(xué)習(xí) (ML) 中最常用的腳本語言之一虫腋。根據(jù)“ PopularitY of Programming Languages ”,Python 是 Google 上搜索次數(shù)最多的語言稀余。除了作為將各種 DS/ML 解決方案連接在一起的出色膠水語言之外悦冀,它還有許多庫可以對(duì)數(shù)據(jù)進(jìn)行虛擬處理。
大約一個(gè)月后睛琳,我們獲得了 Python 的全新年度版本:3.11 版盒蟆。我對(duì)這個(gè)新版本感到非常興奮,因?yàn)檫@個(gè)版本的主要特點(diǎn)是速度顯著提高师骗。
要了解 Python 3.11 真正的速度有多快历等,最好的方法是自己運(yùn)行測試。
對(duì)編程語言進(jìn)行基準(zhǔn)測試并非易事辟癌。當(dāng)您閱讀x比y快時(shí)寒屯,您應(yīng)該始終對(duì)結(jié)果持保留態(tài)度。一種算法的實(shí)現(xiàn)可能比x更好愿待,而另一種算法在y上更好浩螺。對(duì)于我們的基準(zhǔn)測試靴患,它有點(diǎn)簡單,因?yàn)槲覀冋卺槍?duì) Python 測試 Python要出,但我們可能從語言中選擇了僅受到輕微影響的元素鸳君。考慮到這一點(diǎn)患蹂,我想介紹我用來進(jìn)行基準(zhǔn)測試的算法:使用蒙特卡洛方法估計(jì) Pi或颊。
這個(gè)算法的想法很簡單,但是在大學(xué)的一些數(shù)學(xué)課程中第一次看到它讓我大吃一驚传于。我們有一個(gè)大小為2r的正方形囱挑,在這個(gè)正方形中我們擬合一個(gè)半徑為r的圓。現(xiàn)在我們采用一個(gè)隨機(jī)數(shù)生成器沼溜,它在平面上生成數(shù)字:<-r, r>, <-r, r>平挑。圓上的點(diǎn)與正方形上的點(diǎn)之間的比率(讀取:所有點(diǎn))是面積比的近似值系草,我們可以用它來近似 Pi通熄。這在等式中更清楚一點(diǎn):
在 Python 中,我將實(shí)際估計(jì)與測試腳本分開找都,這樣我就可以重復(fù)測試并取平均值唇辨。此處未顯示,但我還使用Argparse對(duì)腳本進(jìn)行了參數(shù)化能耻,這是一個(gè)用于解析來自命令行界面 (CLI) 的參數(shù)的標(biāo)準(zhǔn)庫赏枚。Python 代碼如下所示:
該腳本已準(zhǔn)備好運(yùn)行,但我們希望使用它來測試各種版本的 Python晓猛,而不僅僅是當(dāng)前安裝(或激活)的版本饿幅。測試多個(gè) Python 版本的最簡單方法是使用 Docker。Python 維護(hù)著許多 docker 鏡像戒职。自然是所有受支持的版本诫睬,還有一些生命周期結(jié)束 (EOL) 的版本,例如 2.7 或 3.2帕涌。它還具有用于發(fā)布候選版本的圖像摄凡,例如版本 3.11。要使用 Docker蚓曼,您需要安裝它亲澡。在 Linux 和 Mac 中它相對(duì)容易,在 Windows 中我不太確定纫版,但可能也不難床绪。我建議只安裝 docker CLI,桌面對(duì)我來說太臃腫了。要在容器化 Python 環(huán)境中運(yùn)行本地腳本癞己,請(qǐng)運(yùn)行:
為了自動(dòng)化各種版本的測試膀斋,我們當(dāng)然也會(huì)使用 Python。這個(gè)腳本將簡單地啟動(dòng)一個(gè)子進(jìn)程來啟動(dòng)一個(gè)具有特定 Python 版本的容器痹雅,然后收集結(jié)果仰担。沒什么特別的:
運(yùn)行這些測試時(shí),絕對(duì)數(shù)量因機(jī)器而異绩社,具體取決于處理器(CPU 很重)摔蓝。以下是最近 7 個(gè)主要 Python 版本的結(jié)果:
新的 Python 3.11 每次運(yùn)行耗時(shí) 6.4605 秒。Python 3.5 耗時(shí) 11.3014 秒愉耙。(Python 3.11 快 74.9%)
Python 3.6 耗時(shí) 11.4332 秒贮尉。(Python 3.11 快 77.0%)
Python 3.7 耗時(shí) 10.7465 秒。(Python 3.11 快 66.3%)
Python 3.8 耗時(shí) 10.6904 秒朴沿。(Python 3.11 快 65.5%)
Python 3.9 耗時(shí) 10.9537 秒猜谚。(Python 3.11 快 69.5%)
Python 3.10 耗時(shí) 8.8467 秒。(Python 3.11 快 36.9%)</pre>
Python 3.11 的基準(zhǔn)測試平均耗時(shí) 6.46 秒赌渣。與之前的版本 (3.10) 相比龄毡,這幾乎快了 37%。相當(dāng)令人印象深刻锡垄!3.9 版和 3.10 版之間的差異大致相同,使 3.11 版快了近 70%祭隔!我已經(jīng)在圖 2 中繪制了所有時(shí)間货岭。
在談?wù)撍俣葧r(shí),我們總是有一個(gè)人說:如果你想要速度疾渴,為什么不使用 C千贯。
C 比 Python 快得多!——那個(gè)人
雖然我的 C 有點(diǎn)生銹搞坝,但我還是想試試看搔谴。我使用了 GNU C++,因?yàn)樗鼛в幸粋€(gè)不錯(cuò)的時(shí)間測量庫(chrono)桩撮。找到下面的代碼:
眾所周知敦第,C++ 是一種編譯語言,因此我們需要先編譯源代碼才能使用它店量。
編譯后芜果,只需運(yùn)行構(gòu)建可執(zhí)行文件。輸出應(yīng)該是這樣的:
Pi 約為 3.14227融师,計(jì)算時(shí)間為 0.25728 秒右钾。
Pi 約為 3.14164,計(jì)算時(shí)間為 0.25558 秒。
Pi 約為 3.1423舀射,計(jì)算時(shí)間為 0.25740 秒窘茁。
Pi 約為 3.14108,計(jì)算時(shí)間為 0.25737 秒脆烟。
Pi 約為 3.14261山林,計(jì)算時(shí)間為 0.25664 秒。每個(gè)循環(huán)平均需要 0.25685 秒來計(jì)算浩淘。
我們必須同意那個(gè)人的觀點(diǎn)捌朴,因?yàn)樗娴模ㄩ喿x:真的)很快。執(zhí)行我們之前在 Python 中編寫的相同循環(huán)只需要 0.257 秒张抄。讓我們?cè)谥暗膱D中將其添加為一條線砂蔽,如圖 3 所示。
現(xiàn)在署惯,在對(duì)之前的數(shù)字進(jìn)行了更長時(shí)間的欣賞之后左驾,我們清楚地看到了 Python 獲得的動(dòng)力。自 3.9 版以來极谊,Python 的速度提高了約 35%诡右。Python 開發(fā)人員提到,接下來的幾個(gè)版本將顯著提高速度轻猖,因此帆吻,我們可以假設(shè)這個(gè)速度將保持不變(是的,超級(jí)安全的假設(shè))咙边。
現(xiàn)在的問題是猜煮,在這種勢頭固定的情況下,Python 何時(shí)會(huì)超越 C++ 的時(shí)代败许。為此王带,我們當(dāng)然可以使用外推法來預(yù)測下一個(gè) Python 版本的循環(huán)時(shí)間。這些可以在圖 4 中看到市殷。
圖 4:推斷 Python 速度 -> Python 3.14 的速度將超過 C++愕撰。驚人!(作者圖片)醋寝。
結(jié)果真的很驚人搞挣!保持這個(gè)速度,Python 3.14 將比 C++ 更快音羞。確切地說柿究,循環(huán)時(shí)間為-0.232秒,因此它會(huì)在您想要進(jìn)行計(jì)算之前完成黄选。時(shí)空連續(xù)體中似乎有一個(gè)洞蝇摸,但這些計(jì)算是堅(jiān)如磐石的婶肩。因此,我認(rèn)為我們可能不得不質(zhì)疑愛因斯坦和朋友的工作貌夕。