<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        利用Psyco提升Python運行速度

        來源:懂視網(wǎng) 責編:小采 時間:2020-11-27 14:40:40
        文檔

        利用Psyco提升Python運行速度

        利用Psyco提升Python運行速度:Psyco 是嚴格地在 Python 運行時進行操作的。也就是說,Python 源代碼是通過 python 命令編譯成字節(jié)碼的,所用的方式和以前完全相同(除了為調(diào)用 Psyco 而添加的幾個 import 語句和函數(shù)調(diào)用)。但是當 Python 解釋器運行應(yīng)用程序時,Psyco 會不時地
        推薦度:
        導(dǎo)讀利用Psyco提升Python運行速度:Psyco 是嚴格地在 Python 運行時進行操作的。也就是說,Python 源代碼是通過 python 命令編譯成字節(jié)碼的,所用的方式和以前完全相同(除了為調(diào)用 Psyco 而添加的幾個 import 語句和函數(shù)調(diào)用)。但是當 Python 解釋器運行應(yīng)用程序時,Psyco 會不時地

        Psyco 是嚴格地在 Python 運行時進行操作的。也就是說,Python 源代碼是通過 python 命令編譯成字節(jié)碼的,所用的方式和以前完全相同(除了為調(diào)用 Psyco 而添加的幾個 import 語句和函數(shù)調(diào)用)。但是當 Python 解釋器運行應(yīng)用程序時,Psyco 會不時地檢查,看是否能用一些專門的機器代碼去替換常規(guī)的 Python 字節(jié)碼操作。這種專門的編譯和 Java 即時編譯器所進行的操作非常類似(一般地說,至少是這樣),并且是特定于體系結(jié)構(gòu)的。到現(xiàn)在為止,Psyco 只可用于 i386 CPU 體系結(jié)構(gòu)。Psyco 的妙處在于可以使用您一直在編寫的 Python 代碼(完全一樣!),卻可以讓它運行得更快。

        Psyco 是如何工作的

        要完全理解 Psyco,您可能需要很好地掌握 Python 解釋器的 eval_frame() 函數(shù)和 i386 匯編語言。遺憾的是,我自己不能對其中任何一項發(fā)表專家性的意見 - 但是我想我可以大致不差地概述 Psyco。
        在常規(guī)的 Python 中,eval_frame() 函數(shù)是 Python 解釋器的內(nèi)循環(huán)。eval_frame() 函數(shù)主要察看執(zhí)行上下文中的當前字節(jié)碼,并將控制向外切換到一個適合實現(xiàn)該字節(jié)碼的函數(shù)。支持函數(shù)將做什么的具體細節(jié)通常取決于保存在內(nèi)存中的各種 Python 對象的狀態(tài)。簡單點說,添加 Python 對象“2”和“3”和添加對象“5”和“6”會產(chǎn)生不同的結(jié)果,但是這兩個操作都以類似的方式分派。
        Psyco 用復(fù)合求值單元替代 eval_frame() 函數(shù)。Psyco 有幾種方法可以用來改進 Python 所進行的操作。首先,Psyco 將操作編譯成有點優(yōu)化的機器碼;由于機器碼需要完成的工作和 Python 的分派函數(shù)所要做的事一樣,所以其本身只有些許改進。而且,Psyco 編譯中的“專門的”內(nèi)容不僅僅是對 Python 字節(jié)碼的選擇,Psyco 也要對執(zhí)行上下文中已知的變量值進行專門化。例如,在類似于下面的代碼中,變量 x 在循環(huán)持續(xù)時間內(nèi)是可知的:

        代碼如下:


        x = 5
        l = []
        for i in range(1000):
        l.append(x*i)

        該段代碼的優(yōu)化版本不需要用“x 變量/對象的內(nèi)容”乘每個 i,與之相比,簡單地用 5 乘以每個 i 所用的開銷較少,省略了查找/間接引用這一步。
        除為小型操作創(chuàng)建特定于 i386 的代碼之外,Psyco 還高速緩存這個已編譯的機器碼以備今后重用。如果 Psyco 能夠識別出特定的操作和早先所執(zhí)行的(“專門化的”)操作一樣,那么,它就能依靠這個高速緩存的代碼而不需要再次編譯代碼段。這樣就節(jié)省了一些時間。
        但是,Psyco 中真正省時的原因在于 Psyco 將操作分成三個不同的級別。對于 Psyco,有“運行時”、“編譯時”和“虛擬時”變量。Psyco 根據(jù)需要提高和降低變量的級別。運行時變量只是常規(guī) Python 解釋器處理的原始字節(jié)碼和對象結(jié)構(gòu)。一旦 Psyco 將操作編譯成機器碼,那么編譯時變量就會在機器寄存器和可直接訪問的內(nèi)存位置中表示。
        最有意思的級別是虛擬時變量。在內(nèi)部,一個 Python 變量就是一個有許多成員組成的完整結(jié)構(gòu) - 即使當對象只代表一個整數(shù)時也是如此。Psyco 虛擬時變量代表了需要時可能會被構(gòu)建的 Python 對象,但是這些對象的詳細信息在它們成為 Python 對象之前是被忽略的。例如,考慮如下賦值:
        x = 15 * (14 + (13 - (12 / 11)))
        標準的 Python 會構(gòu)建和破壞許多對象以計算這個值。構(gòu)建一個完整的整數(shù)對象以保存 (12/11) 這個值;然后從臨時對象的結(jié)構(gòu)中“拉”出一個值并用它計算新的臨時對象 (13-PyInt)。而 Psyco 跳過這些對象,只計算這些值,因為它知道“如果需要”,可以從值創(chuàng)建一個對象。

        使用 Psyco

        解釋 Psyco 相對比較困難,但是使用 Psyco 就非常容易了?;旧?,其全部內(nèi)容就是告訴 Psyco 模塊哪個函數(shù)/方法要“專門化”。任何 Python 函數(shù)和類本身的代碼都不需進行更改。
        有幾種方法可以指定 Psyco 應(yīng)該做什么?!矮C槍(shotgun)”方法使得隨處都可使用 Psyco 即時操作。要做到這點,把下列行置于模塊頂端:

        代碼如下:


        import psyco ; psyco.jit()
        from psyco.classes import *

        第一行告訴 Psyco 對所有全局函數(shù)“發(fā)揮其魔力”。第二行(在 Python 2.2 及以上版本中)告訴 Psyco 對類方法執(zhí)行相同的操作。為了更精確地確定 Psyco 的行為,可以使用下列命令:
        psyco.bind(somefunc) # or method, class
        newname = psyco.proxy(func)
        第二種形式把 func 作為標準的 Python 函數(shù),但是優(yōu)化了涉及 newname 的調(diào)用。除了測試和調(diào)試之外的幾乎所有的情況下,您都將使用 psyco.bind() 形式。

        Psyco 的性能

        盡管 Psyco 如此神奇,使用它仍然需要一點思考和測試。主要是要明白 Psyco 對于處理多次循環(huán)的塊是很有用的,而且它知道如何優(yōu)化涉及整數(shù)和浮點數(shù)的操作。對于非循環(huán)函數(shù)和其它類型對象的操作,Psyco 多半只會增加其分析和內(nèi)部編譯的開銷。而且,對于含有大量函數(shù)和類的應(yīng)用程序來說,在整個應(yīng)用程序范圍啟用 Psyco,會在機器碼編譯和用于這一高速緩存的內(nèi)存使用方面增加大量的負擔。有選擇性地綁定那些可以從 Psyco 的優(yōu)化中獲得最大收益的函數(shù),這樣會好得多。
        我以十分幼稚的方式開始了我的測試過程。我僅僅考慮了我近來運行的、但還未考慮加速的應(yīng)用程序。想到的第一個示例是用來將我即將出版的書稿(Text Processing in Python)轉(zhuǎn)換成 LaTeX 格式的文本操作程序。該應(yīng)用程序使用了一些字符串方法、一些正則表達式和一些主要由正則表達式和字符串匹配所驅(qū)動的程序邏輯。實際上將它用作 Psyco 的測試候選是很糟的選擇,但是我還是使用了,就這么開始了。
        第一遍測試中,我所做的就是將 psyco.jit() 添加到腳本頂端。這做起來一點都不費力。遺憾的是,結(jié)果(意料當中)很令人失望。原先腳本運行要花費 8.5 秒,經(jīng)過 Psyco 的“加速”后它大概要運行 12 秒。真差勁!我猜測大概是即時編譯所需的啟動開銷拖累了運行時間。因此接下來我試著處理一個更大的輸入文件(由原來那個輸入文件的多個副本組成)。這次獲得了小小的成功,將運行時間從 120 秒左右減到了 110 秒。幾次運行中的加速效果比較一致,但是效果都不顯著。
        本處理候選項的第二遍測試中。我只添加了 psyco.bind(main) 這一行,而不是添加一個總的 psyco.jit() 調(diào)用,因為 main() 函數(shù)確實要循環(huán)多次(但是僅利用了最少的整數(shù)運算)。這里的結(jié)果名義上要比前面好。這種方法將正常的運行時間削減了十分之幾秒,在較大的輸入版本的情況下削減了數(shù)秒鐘。但是仍然沒有引入矚目的結(jié)果發(fā)生(但也沒產(chǎn)生什么害處)。

        為進行更恰當?shù)?Psyco 測試,我搜尋出我在以前的文章里編寫的一些神經(jīng)網(wǎng)絡(luò)代碼(請參閱“參考資料”)。這個“代碼識別器(code_recognizer)”應(yīng)用程序可以經(jīng)“訓練”用于識別不同編程語言編寫的不同 ASCII 值的可能分布情況。類似于這樣的東西可能在猜測文件類型方面(比方說丟失的網(wǎng)絡(luò)信息包)將很有用;但是,關(guān)于“訓練”些什么,代碼實際上完全是通用的 - 它能很容易地學會識別面孔、聲音或潮汐模式。任何情況下,“代碼識別器”都基于 Python 庫 bpnn,Psyco 4.0 分發(fā)版也包含(以修正的形式)了該庫作為測試用例。在本文中,對“代碼識別器”要重點了解它做了許多浮點運算循環(huán)并花費了很長的運行時間。這里我們已經(jīng)有了一個能用于 Psyco 測試的好的候選用例。
        使用了一段時間后,我建立了有關(guān) Psyco 用法的一些詳細信息。對于這種只有少量類和函數(shù)的應(yīng)用程序,使用即時綁定還是目標綁定沒有太大區(qū)別。但最佳的結(jié)果是,通過有選擇性地綁定最優(yōu)化類,仍可得到幾個百分點的改進。然而,更值得注意的是要理解 Psyco 綁定的作用域,這一點很重要。
        code_recognizer.py 腳本包括類似于下面的這些行:

        從 bpnn 導(dǎo)入 NN
        class NN2(NN):
        # customized output methods, math core inherited
        也就是說,從 Psyco 的觀點來看,有趣的事情在類 bpnn.NN 之中。把 psyco.jit() 或 psyco.bind(NN2) 添加到 code_recognizer.py 腳本中起不了什么作用。要使 Psyco 進行期望的優(yōu)化,需要將 psyco.bind(NN) 添加到 code_recognizer.py 或者將 psyco.jit() 添加到 bpnn.py。與您可能假設(shè)的情況相反,即時優(yōu)化不在創(chuàng)建實例時或方法運行時發(fā)生,而是在定義類的作用域內(nèi)發(fā)生。另外,綁定派生類不會專門化其從其它地方繼承的方法。
        一旦找到適當?shù)?Psyco 綁定的細微的詳細信息,那么加速效果是相當明顯的。使用參考文章中提供的相同測試用例和訓練方法(500 個訓練模式,1000 個訓練迭代),神經(jīng)網(wǎng)絡(luò)訓練時間從 2000 秒左右減到了 600 秒左右 - 提速了 3 倍多。將迭代次數(shù)降到 10,加速的倍數(shù)也成比例降低(但對神經(jīng)網(wǎng)絡(luò)的識別能力無效),迭代的中間數(shù)值也會如此變化。
        我發(fā)現(xiàn)使用兩行新代碼就能將運行時間從超過半小時減到 10 分鐘左右,效果非常顯著。這種加速仍可能比 C 編寫的類似應(yīng)用程序的速度慢,而且它肯定比幾個獨立的 Psyco 測試用例所反映出的 100 倍加速要慢。但是這種應(yīng)用程序是相當“真實的”,而且在許多環(huán)境中這些改進已經(jīng)是夠顯著的了。

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        利用Psyco提升Python運行速度

        利用Psyco提升Python運行速度:Psyco 是嚴格地在 Python 運行時進行操作的。也就是說,Python 源代碼是通過 python 命令編譯成字節(jié)碼的,所用的方式和以前完全相同(除了為調(diào)用 Psyco 而添加的幾個 import 語句和函數(shù)調(diào)用)。但是當 Python 解釋器運行應(yīng)用程序時,Psyco 會不時地
        推薦度:
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 日韩a毛片免费观看| 99久久免费国产精精品| 亚洲中文无码mv| 亚洲熟妇无码八V在线播放 | 亚洲人成综合网站7777香蕉| 精品久久久久久久久亚洲偷窥女厕| 成在线人视频免费视频| 国产成人精品免费视频大| 国产成人在线观看免费网站| 国产精品亚洲精品日韩已方| 久久精品国产亚洲AV高清热| 久久久亚洲精华液精华液精华液 | 美女被免费网站91色| 91手机看片国产永久免费| 亚洲精品无码专区2| 亚洲六月丁香婷婷综合| 久草免费福利在线| 亚洲中文字幕无码不卡电影| 亚洲成a人片在线不卡一二三区| 久久永久免费人妻精品| 国产真人无遮挡作爱免费视频| 久久亚洲精品高潮综合色a片| 亚洲成年看片在线观看| 亚洲中文字幕AV每天更新| 免费在线黄色网址| 亚洲欧美自偷自拍另类视| 亚洲三级在线免费观看| 亚洲av色香蕉一区二区三区| 亚洲日韩中文在线精品第一| 免费无码VA一区二区三区| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 免费乱理伦在线播放| 中文成人久久久久影院免费观看| 中文字幕亚洲综合久久2| 男人天堂免费视频| 亚洲制服在线观看| 99久久免费中文字幕精品| 亚洲午夜福利在线视频| 亚洲人成无码网站| a级片免费在线播放| 国产成人精品日本亚洲18图|