国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

探究數組排序提升Python程序的循環的運行效率的原因

2020-02-23 00:29:07
字體:
來源:轉載
供稿:網友

早上我偶然看見一篇介紹兩個Python腳本的博文,其中一個效率更高。這篇博文已經被刪除,所以我沒辦法給出文章鏈接,但腳本基本可以歸結如下:
fast.py
 

import timea = [i for i in range(1000000)]sum = 0t1 = time.time()for i in a:  sum = sum + it2 = time.time()print t2-t1

slow.py
 

import timefrom random import shufflea = [i for i in range(1000000)]shuffle(a)sum = 0t1 = time.time()for i in a:  sum = sum + it2 = time.time()print t2-t1

如你所見,兩個腳本有完全相同的行為。都產生一個包含前一百萬個整數的列表,并打印對這些整數求和的時間。唯一的不同是 slow.py 先將整數隨機排序。盡管這看起來有些奇怪,似乎隨機化足夠將程序明顯變慢。在我機器上,運行的Python2.7.3, fast.py 始終比 slow.py 快十分之一秒(fast.py 執行大約耗時四分之三秒,這是不平常的增速)。你不妨也試試看。(我沒有在Python3上測試,但結果應該不會差太多。)

那為什么列表元素隨機化會導致這么明顯的減速呢?博文的原作者把這記作“分支預測(branch prediction)”。如果你對這個術語不熟悉,可以在 StackOverflow 的提問中看看,這里很好地解釋了這個概念。(我的疑慮是原文的原作者遇到了這個問題或者與此類似的問題,并把這個想法應用到不太適合應用的Python片段中。)

當然,我懷疑分支預測(branch prediction)是否是真正導致問題的原因。在這份Python代碼中沒有頂層條件分支,而且合乎情理的是兩個腳本在循環體內有嚴格一致的分支。程序中沒有哪一部分是以這些整數為條件的,并且每個列表的元素都是不依賴于數據本身的。當然,我還是不確定python是否算得上足夠“底層”,以至于CPU級別的分支預測能夠成為python腳本性能分析中的一個因素。Python畢竟是一門高級語言。

因此,如果不是分支預測的原因,那為什么 slow.py 會這么慢?通過一點研究,經過一些“失敗的開端”之后,我覺得自己找到了問題。這個答案需要對Python內部虛擬機有點熟悉。

失敗的開端:列表vs.生成器(lists and generators)

我的第一想法是Python對排序的列表[i for i in range(1000000)] 的處理效率要比隨機列表高。換句話說,這個列表可以用下面的生成器替代:

def numbers():  i = 0  while i < 1000000:    yield i    i += 1

我想這可能在時間效率上更高效些。畢竟,如果Python在內部使用生成器替代真正的列表可以避免在內存中一次保存所有整數的麻煩,這可以節省很多開銷。slow.py 中的隨機列表不能輕易的被一個簡單生成器捕獲,所有VM(虛擬機)無法進行這樣的優化。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 大名县| 承德县| 阿克陶县| 抚松县| 和林格尔县| 长岭县| 得荣县| 高淳县| 福清市| 上饶市| 美姑县| 青州市| 新野县| 定陶县| 大田县| 鹤岗市| 碌曲县| 镇巴县| 巨野县| 怀安县| 贡觉县| 长白| 永定县| 尖扎县| 调兵山市| 奉化市| 武陟县| 通江县| 西丰县| 汤原县| 那曲县| 涿鹿县| 阿坝县| 长春市| 师宗县| 中宁县| 中宁县| 德惠市| 海兴县| 阜康市| 得荣县|