欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

利用Psyco提升Python運(yùn)行速度

系統(tǒng) 1865 0

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

Psyco 是如何工作的

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

復(fù)制代碼 代碼如下:

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

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

使用 Psyco

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

復(fù)制代碼 代碼如下:

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

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

Psyco 的性能

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

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

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


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 一级毛片一级毛片一级毛片 | www.82gan.com| 欧美不卡| 亚洲人人草 | 久久99精品视免费看 | 中文字幕欧美在线 | 波多久久夜色精品国产 | 偿还的影视高清在线观看 | 亲爱的热爱的电视剧免费观看 | 麻豆精品国产自产在线 | 欧美日韩一二区 | 国产精品无码专区在线观看 | 国产激情一区二区三区 | 午夜资源在线 | 国产女人久久精品 | 免费国产va在线观看视频 | 91成人午夜性a一级毛片 | 久久伊人精品 | 激情丁香开心久久综合 | 国产精品久久久免费视频 | 欧美第一页草草影院浮力 | 国产精品久久久久不卡 | 美女视频黄在线观看 | 欧美成人手机在线视频 | 青青青青久久久久国产的 | 日本在线国产 | 国产日本三级欧美三级妇三级四 | 国产日韩欧美在线观看不卡 | 日韩中文一区 | 素人视频在线观看免费 | 小明永久成人一区二区 | 欧美调教视频 | 日本一本久草 | 亚洲色四在线视频观看 | 欧美日韩亚洲在线 | 色噜噜狠狠色综合欧洲selulu | 国产精品中文在线 | 精品免费国产一区二区三区 | 国产精品精品 | 国产美女一区二区 | 黑色丝袜美女被狂躁 |