Python很慢?不一定哦
請注意,這有點夸張。
首先,我要說明我是專業(yè)從事python工作的,我做出了許多開源貢獻,并且我所有的業(yè)余愛好項目都使用python進行。我喜歡python。
但這很慢。
這是Reddit等論壇上的常見主題,人們說您不能使用python,因為它運行緩慢。是的,我們都知道python很慢。但是我們也知道,通常會使事情變慢的不是語言,而是算法。
是的,與C語言相比,python語言的運行速度非常慢,但這并不是python速度慢的99%。 Python之所以緩慢,是因為許多(即使不是大多數(shù))Python程序員不在乎或不了解他們所做工作對性能的總體影響。編寫網(wǎng)絡應用程序時基本上可以這樣做,但是如果編寫的庫可供成千上萬,十萬甚至一百萬的人使用,則可能會對性能產(chǎn)生重大影響。
讓我們看一些Python運行緩慢的實際例子:
此處顯示的工具:
- pip是用于安裝python庫的工具
- virtualenv是用于創(chuàng)建封閉環(huán)境的工具,因此您無需全局安裝所有軟件包
- pytest是使用最廣泛的測試庫(也許標準庫中的unittest使用得更多,但至少非常接近)
我之所以選擇這些工具,是因為這是大多數(shù)人與python的首次互動,而這是我們專業(yè)人士每天與之互動的東西。
- > time pip --version
- 0.34 seconds
- > time virtualenv -p (which python3) venv
- 6.24 seconds
- > time pytest # in an EMPTY directory
- 0.32 seconds
- > time pip install pytest # already installed!!!
- 0.85 seconds
這些測量是普遍的,因為它們是在新環(huán)境中且具有熱緩存(我對具有冷磁盤緩存的virtualenv進行了15秒鐘的測量)。 如果您的虛擬環(huán)境具有很多依賴性,那么pip安裝(同樣不做任何事情)的時間會增加。 很多。 我在另一個項目中測量了2.1秒。
在這里算法才是問題,不是python。 我的意思是,當我們解決算法問題時,語言將成為問題,而且它永遠不可能比更快的語言快,但是我們幾乎與任何地方都差不多。
我對此不夠強調(diào):python的基本工具鏈比它所需的要慢一個數(shù)量級。 有時更多。
Imports(導入)
在python中導入的慣用方式是個大問題。 在python中使用說說請求,您確實會在文件頂部導入請求,大多數(shù)人會認為這是免費的或接近免費的。 在python中,它并不是完全免費的,實際上,它要求導入urllib2,這是很慢的部分。 因此,人們認為請求的導入是免費的,而請求的作者則認為urllib2的導入是免費的。 到處都是這樣:成千上萬的人都認為進口是免費的。 他們不是。
我最??吹降囊环N模式是:
- try:
- import numpy
- NUMPY_AVAILABLE = True
- except ImportError:
- NUMPY_AVAILABLE = False
并且在導入時運行。我們什么時候在庫中使用該標志?通常從不,并且numpy導入非常昂貴。我的機器上200ms。因此,對于您的應用程序而言,它的啟動性能非常出色,因為它的功能在啟動路徑中沒有使用,在許多情況下根本沒有使用。
開發(fā)時,這非常令人沮喪,因為您平均可以在整個工作日平均每分鐘重新啟動一次該過程。
我很高興看到一年以前,因此pytz停止在導入時解析其整個時區(qū)數(shù)據(jù)庫。從Django(可以說是最流行的Web框架)的啟動開始,這節(jié)省了約100毫秒的時間。現(xiàn)在考慮一下,這種微小的變化將在10年內(nèi)節(jié)省多少千瓦時。每次運行測試時,每次啟動Web Worker時,都會在每個使用Django的站點上進行。這僅適用于Django!許多其他庫和程序都使用pytz。
千紙之死
另一個問題是,人們認為“哦,啟動時只有10毫秒,這沒什么大不了的”,但是如果該啟動每天進行數(shù)百萬次,那將是真實數(shù)字。對于進口來說,這是正確的,但在更多事情上也是如此。后續(xù)問題是,人們已經(jīng)引入了100種此類減速后,就會認為“僅再增加10毫秒”。因此,現(xiàn)在您只需要在1秒的基礎上再加上10毫秒,即1%。沒什么大不了的!因此,現(xiàn)在可以再增加10毫秒,這略低于1%。每次您使其變慢時,它就會變得更便宜(以百分比為單位),以使其變得更慢。
請不要使用這種邏輯!
上面的pip安裝示例是一個很好的案例研究。從磁盤加載字典并檢查其是否包含字符串“ pytest”將比python的啟動時間(約30毫秒)少。但這不是pip在做什么,它正在文件系統(tǒng)中運行,甚至正在加載python文件以獲取其版本號(為什么?我沒有詢問它們!為什么它們?nèi)匀粵]有以有效的格式存儲?)。
在pytest中,我們有一個類似的問題,性能回歸已被引入了上千次,但是現(xiàn)在一切都很緩慢,并且沒有明顯的方法來擺脫這種情況。我已經(jīng)提供了一些補丁,但是由于我在進行優(yōu)化時進行了其他更改,因此我獲得的大部分收益都被抹去了!
最后,我放棄了提交補丁程序,并構(gòu)建了一個名為hammett的新測試運行程序,該測試運行程序與pytest兼容,但速度更快。我的意思是走得更快。我希望,如果有替代方案,人們可以看到存在另一個可能運行緩慢的世界。
我們?nèi)绾问筽ython更快?
我們需要關心這一問題。
我們需要了解進口不是免費的。
我們需要研究整個生態(tài)系統(tǒng)的基本構(gòu)建模塊,或者解決基本程序和庫中的性能問題,或者替換它們。
我們需要衡量。
一些開始的地方:
- pytest:代替我使用hammett,或敦促pytest的向后兼容性大幅度中斷,以提高性能
- pip:至少緩存一些結(jié)果!我應該能夠在執(zhí)行每個命令之前運行“ pip install -r requirements.txt”,而不會注意到它
- virtualenv:我還沒有研究過,但是似乎可以寫1218個文件,總計11.6MB,可以加快速度,或者避免做一些工作
- 編寫基準:這可能是最簡單的。例如,您可以將工具與其他語言的同類工具進行基準測試。我們至少應該知道我們是否比例如java慢一百倍。
更新:
事實證明,virtualenv家伙已經(jīng)在此之上了!現(xiàn)在,版本20需要0.8秒才能完成與之前花費6.4相同的任務。為此,virtualenv團隊值得高度贊揚!
原文網(wǎng)址:https://kodare.net/2020/05/19/python-is-slow-does-not-have-to-be.html