成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

在后臺的Python:眾多程序員無法攻克的難題

開發 后端
很多Python程序員并不知道這個難題,因為這需要深入理解Python的運行原理。本文就將解答“運行python代碼時會發生什么?”,重點介紹最流行的Python工具CPython。如果你不知道正在使用何種Python工具,那么你90%使用的是CPython。

 [[378303]]

先看兩個超級簡單的代碼。

  1. for i inrange(10**7): 
  2.                 x = i %5 

代碼1:簡單代碼

  1. defmain(): 
  2.           for i inrange(10**7): 
  3.               x = i %5 
  4.        main() 

代碼2:定義了一個主函數來運行相同的簡單代碼。

兩個代碼都執行一個虛擬任務。取0到1000萬之間的數字(通過for循環),并計算其模(余數)為5,到目前為止操作非常簡單。那么,測量代碼的運行時間是多少呢?

  1. import time 
  2.              start_time = time.time() 
  3.       for i inrange(10**7): 
  4.          x = i %5 
  5.       finish_time = time.time() 
  6.              print("Duration:{} msec".format((finish_time-start_time)*1000)) 

在代碼1中添加一個簡單的計時器

  1. import time 
  2.              defmain(): 
  3.           for i inrange(10**7): 
  4.              x = i %5 
  5.              start_time = time.time() 
  6.       main() 
  7.       finish_time = time.time() 
  8.              print("Duration:{} msec".format((finish_time-start_time)*1000)) 

在代碼2中添加一個簡單的計時器

在兩個代碼中添加一個簡單的計時器來測量各自的運行時間。由于兩個代碼執行相同的簡單任務,預計運行時間也相同。當然,如果運行時間真的相同,本文就沒有存在的必要了。事實上,代碼1和代碼2的運行時間分別為739毫秒和434毫秒,驚訝吧!

很多Python程序員并不知道這個難題,因為這需要深入理解Python的運行原理。本文就將解答“運行python代碼時會發生什么?”,重點介紹最流行的Python工具CPython。如果你不知道正在使用何種Python工具,那么你90%使用的是CPython。

以下是運行源代碼時的情況:

首先,源代碼通過“詞法分析”程序被分解成標記,例如, x=1將被分解成x, =,和1。然后,通過“句法分析”的過程,這些標記被組織成抽象語法樹(AST),之后“編譯器”將所有內容轉換成為一個叫做“字節碼”的抽象代碼。

在Python中,不像C、C++、Java等語言,編譯器不會獲取“源代碼”并將其轉換為“機器代碼”,理解這一點很重要。與之相反,編譯器可接受“源代碼”并且將其轉換為“字節碼”。解釋器的任務是獲取字節碼并以機器能夠理解的方式運行。

在Python運行代碼的四個步驟中,解釋器負責最繁重的工作。而其他三個步驟不會處理太多的任務。因此,任何時候想要研究Python程序的性能時,應該查看解釋步驟并尋找一些線索。

解釋器讀取字節碼并運行其指令。如果字節碼類似于菜譜,那么指令便是菜譜中的不同步驟。如果字節碼可讀取,就可能找到關于上述謎題的一些線索。使用 dis包來查看字節碼指令。dis是一個Python包,用于分析和解碼字節碼,并以人們可以理解的方式顯示出來。dis.dis() 的輸出結構如下:

本文不詳細介紹dis包的細節,只關注Operation Named的一列。Operation name指示Python解釋器的行為。如果你非常好奇,那么名為ceval.c的文件可以回答。以上兩個代碼都運行了dis.dis(),為了簡化操作,本文突出顯示重要部分,即循環部分。下圖顯示了這兩個代碼的字節碼:

如圖所示,兩個代碼在給定的指令方面非常相似。但是,仔細觀察,會發現字節碼中有一些細微的(但是很重要的)差異。在代碼1中,可以看到STORE_NAME和LOAD_NAME,但是在代碼2中,可以看到STORE_FAST和LOAD_FAST。運行時間的差異似乎是由于這兩種指令類型的不同造成的。可以查看ceval.c文件來了解其中的差異。

簡而言之,在代碼1中,解釋器處理變量i和x的方式與代碼2不同(注意_NAME和_FAST后綴)。代碼1中,i和x都是全局變量,而CPython將這些變量存儲在字典數據結構中,這使得加載過程比存儲在固定大小數組中的局部變量耗時更久。與字典相比,從固定大小的數組中檢索變量要快得多。

為什么Python這么做?很簡單,因為在主代碼中,不知道有多少變量會出現,但是在一個函數中變量的數量是固定的。

如果這是原因所在,來做個測試:把解釋器打亂,在代碼2(快速代碼)中將x和i變量定義為全局變量,并再次測量運行時間。這是改變后的代碼2:

  1. defmain(): 
  2.           global i, x 
  3.           for i inrange(10**7): 
  4.               x = i %5 
  5.        main() 

代碼3與代碼2相同,只是定義了變量i和x,以查看全局變量是否是導致難題代碼性能變慢的原因。

運行代碼3,用時805毫秒(代碼2用時434 毫秒)。代碼3的用時非常接近于代碼1(即739毫秒)。這正如預計的,處理全局變量比處理局部變量(固定大小的數組與字典)花費更多的時間。

如你所見,只需要了解一點關于Python解釋器的工作原理,以及從dis庫中得到幫助,這個難題即可迎刃而解。

責任編輯:武曉燕 來源: 讀芯術
相關推薦

2021-01-24 22:46:07

Python開發程序員

2015-06-17 10:05:41

編程 程序員

2013-08-20 09:33:59

程序員

2011-05-13 14:34:02

程序員

2018-10-31 11:17:55

程序員女朋友面試

2012-11-22 14:00:26

程序員

2017-11-14 21:30:15

2012-06-23 17:21:18

程序員

2009-12-14 09:29:00

程序員

2010-08-27 10:34:51

程序員

2012-02-14 09:13:51

程序員

2012-03-13 10:55:00

程序員

2015-09-24 08:43:13

程序員未來

2015-05-26 09:17:34

程序員泛泛涉獵

2012-11-08 09:49:30

C++Java程序員

2013-04-15 10:55:09

程序員

2009-06-18 13:36:00

亂碼問題

2023-09-26 01:27:09

AI程序員軟件

2013-06-14 11:16:14

2013-07-17 18:00:02

程序員禁忌程序員錯誤程序員bug
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 黄色免费在线观看网站 | 国产欧美一区二区三区久久手机版 | 亚洲一区二区视频在线观看 | 草久久| 人人看人人草 | 自拍视频网 | 国产精品免费福利 | 亚洲欧美精品一区 | 日韩精品极品视频在线观看免费 | 久久久久久久成人 | aaa一区| 国产欧美精品区一区二区三区 | 亚洲欧美国产精品久久 | av免费观看网站 | 日韩精品一区二区三区在线播放 | 2022精品国偷自产免费观看 | 国产高清精品在线 | 日本偷偷操 | 亚洲国产成人精品女人 | 欧美日韩亚洲在线 | 久久久久无码国产精品一区 | 国产成人av在线播放 | 国内久久 | 99久久婷婷 | 天堂中文资源在线 | 亚洲精品女优 | 黄色一级片在线播放 | 欧美高清视频一区 | 91黄在线观看 | 日韩欧美二区 | 亚洲一页| 欧美日韩成人网 | 在线国产小视频 | 色综合欧美 | 91久色| 日韩在线中文字幕 | 欧洲妇女成人淫片aaa视频 | 国产精品日韩一区二区 | 黄色片网此| 一级做a爰片性色毛片视频停止 | 国产精品一区二 |