ページ

2010年4月30日

geventのサンプルを動かしてみたよ

geventでごにょごにょ遊ぶ前に、サンプルを動かしてみました。



urls = ['http://www.google.com',
"他いろいろ"]

import time
import urllib2

proxy = {'http':'http://192.168.0.230:3128/'}
proxy_handler = urllib2.ProxyHandler(proxy)
opener = urllib2.build_opener(proxy_handler)
urllib2.install_opener(opener)

def got(url):
print "url" + url
data = opener.open(url).read()
print "url done " + url
return 0

start = time.time()
jobs = [got(url) for url in urls]
end = time.time()

print end - start
上のコードが普通のコードです。会社の中でやったので、proxyが通るように書いています。ちゃんと比較するんならスレッドにすべきなのかも知れませんが、手抜きです。

で、次のコードがgeventを使ったコードです。おサルさんをけしかける(monkey.patch_all())と、ネットワークが非同期で動くようになります。

urls = ['http://www.google.com',
"他いろいろ"]

import gevent
from gevent import monkey
monkey.patch_all()

import time
import urllib2

proxy = {'http':'http://192.168.0.230:3128/'}
proxy_handler = urllib2.ProxyHandler(proxy)
opener = urllib2.build_opener(proxy_handler)
urllib2.install_opener(opener)

def got(url):
print "url" + url
data = opener.open(url).read()
print "url done " + url
return 0

start = time.time()
jobs = [gevent.spawn(got, url) for url in urls]
gevent.joinall(jobs)
end = time.time()

print end - start
で、geventを使わない方はこんな感じの出力です。

urlhttp://www.google.com
url done http://www.google.com
urlhttp://xxx1
url done http://xxx1
urlhttp://xxx2
url done http://xxx2
urlhttp://xxx3
url done http://xxx3
1.55014014244
順次実行されていきます。次がeventletを使った奴。

urlhttp://www.google.com
urlhttp://xxx1
urlhttp://xxx2
urlhttp://xxx3
url done http://xxx1
url done http://xxx2
url done http://www.google.com
url done http://xxx3
1.30022597313
と言うことで、httpへのアクセスがブロックせずに動作していることが分かります。いや、わかりにくいか・・・・。実行時間は、最初のコードがスレッドを使っていないので、公平ではありません。厳密に見ると、メモリ使用量とかCPUの使用率とか、Pythonのスレッドモデルとかいろいろありますが、まあ、今回は感じをつかむと言うことで・・・。eventletを使うとパッケージが違いますがほぼ同じコードです。
これをTwistedのコールバックでも、waitfordeferredでもめんどいし、標準ライブラリをそのまま使うこともできないので、大変です。まあ、eventlet + twistedの組み合わせはなしと言うことで・・・。

とにかく、コールバックじゃないと、やっぱ楽だな〜。他のライブラリがそのまま使えるのも楽だな〜。

0 件のコメント: