stackless python初體驗


stackless python真是毀三觀,算斐波那契數列,n為100000(十萬),運行時間2。2秒左右
這里寫一下感悟:
stackless python從字面上理解就是沒有棧的python,怎么做到沒有棧呢?基於堆棧的語言是怎么實現的:
1、一般將函數的調用推進棧里面,后入棧單元計算完之后,先入棧的才能夠完成
2、棧里面的單元怎么通信呢?今天剛好做完DDos攻擊的實驗,提醒我了這點:棧的單元通過入口地址和返回地址與它的前后單元通信。
3、棧的厚度有限制,貌似是1000多,就是說,迭代到1000多層就不能繼續進棧了,當然可以將層數認為調高。大概原理就是這樣。
 
stackless python說,我不要棧!那么不用棧是怎么寫程序呢?
1、他用一種叫做tasklet的東西代替了堆棧里面的單元
2、這些單元通過一種叫做channel的機制來通信
3、因為不是基於堆棧,所以這些tasklet的數量你想要多少有多少,就像這里,100000
 
tasklet又叫做微線程(microthread),所以說,是在python進程里面的一個線程再分出來的“thread”。它被設計為在各個tasklet之間的切換開銷遠遠小於系統的線程。
一個tasklet可以通過往另外一個tasklet的channel來發送信息,自己進入阻塞狀態,然后激活另一個tasklet
 
以斐波那契數列為例:
往常,我們使用遞歸求斐波那契數列的時候。。。。。就不說了,大家都懂
如果換做stackless的版本呢?
堆棧沒了,我們有一個個的tasklet,這些tasklet里面包含了一個channel,一個個的tasklet
通過將自己的channel傳給下一個tasklet,下一個channel通過將自己的處理結果發送到前一個tasklet的channel里面實現通信。
 
其實如果用“微線程”的方式去理解tasklet,你可以認為,它其實是有“堆棧”的,就像系統級別的線程一樣,但是這個堆棧僅僅是用於調用一個函數,或者說,將這個函數的調用放進一個tasklet里面。
 
通過這種方式(其實我不知道自己說明白沒有。。),就形成了一條tasklet鏈,如果我們將他們想象成層疊的形狀,其實跟堆棧的形狀也是挺相似的,但是他們不叫堆棧,叫做tasklet,而且性能比堆棧的性能要好。記住這種工具的名字,它叫做stackless python。
 
下面是計算斐波那契數列的代碼:
import stackless
 
dic = {}
 
def factorial(n):
if n == 1:
return 1
elif n == 2:
return 2
else:
return task(n-1) + task(n-2)
 
 
def task(n):
if str(n) in dic:
return dic[str(n)]
chann = stackless.channel()
stackless.tasklet(compute)(n,chann)
result = chann.receive()
dic[str(n)] = result
return result
 
def compute(n,chann):
return chann.send(factorial(n))
 
 
print factorial(100000)
 
然后用堆棧版本試了一下,先將python堆棧的層數上線改了100000,運行,大概1.3秒到1.5秒,其實stackless與堆棧相比沒有多大優勢。
 
堆棧版本代碼:
import sys
sys.setrecursionlimit(100000)
 
dic = {}
 
def factorial(n):
if n == 1:
return 1
elif n == 2:
return 2
elif str(n) in dic:
return dic[str(n)]
else:
a = factorial(n-1)
if str(n-1) not in dic:
dic[str(n-1)] = a
b = factorial(n-2)
if str(n-2) not in dic:
dic[str(n-2)] = a
return a + b
 
 
print factorial(99999)
 
這里僅僅講到的是stackless的這么一種用法,一般stackless的用途還是在替代系統線程這方面,用來做並發有c語言級別的性能,這個以后再做測試 [呵呵] [呵呵] [呵呵]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM