* pythonのhashとdbm速度調査 [#xc724912]
** メモリーとDiskの速度を比較する。 [#x816818b]

** dbmとは、 [#q25b88eb]
pythonには、dbmと言って、データの内容を保存する仕組みがある。

保存の仕方は、次みたいにする。
 >>> import anydbm #anydbmをインポート
 >>> d=anydbm.open('test.dbm','n') #test.dbmと言う名前で、作成。nは常に新しく作る。
 >>> d['foo']='bar' #hashの様に、keyを決めて、内容を書き込む(キー、値ともに、文字列で書き込むこと)。
 >>> d['foo'] #参照する際は、キーで参照
 'bar'
 >>>exit() #一旦抜けて見る。
 
 >>> import anydbm #再度やって見る。
 >>> d=anydbm.open('test.dbm','c') #test.dbmの開く。
 >>> for k in d: #hashの様にfor でキーを取得できる。
 ...   print k
 ...
 foo
 >>> d['foo'] #キーfooに結びついた値が取れる。
 'bar'

dbmは、NoSQLの一種、(TokyoCabinet)等に使われる技術でもある。

** hashとdbmの速度調査 [#w0dcd4e6]

それでは、dbmとhashではどのくらい速度が違うのか試して見る。
言い換えると、dbmは、ディスクへの保存、hashは、メモリーへの保存である。つまり、diskとmemoryの速度差を見ることでもある。
dbmは、dbhashを使用。pythonのVersionは、2.6だったと思う。使用したOSは、ubuntu9である。

1000から一億までの数字を、KeyとValueにして、試して見た。
心臓部のソースコードは以下。順次アクセスして、writeとreadを試している。

 @t_profile('write')
 def write(db,limit):
     for i in range(limit):
         db[str(i)]=str(i) #dbmは文字列しかキー、値にならないので、文字列化
     return limit
 
 @t_profile('read')
 def read(db,limit):
     for i in range(limit):
         v=db[str(i)] 
         assert(i==int(v))
     return limit

その際の、QPS(Query Per Second)を計測する。

** AmazonEC2上のhash,dbm速度調査 [#n4a57721]
試したのは、amazon EC2上のx.largeインスタンス。OSは、ubuntu9.04である。

*** EC2上でのdbm,hashの速度調査 [#za7d2d48]

|count|hash read(QPS)|hash write(QPS)|dbm read(QPS)|dbm write(QPS)|
|10000|1000000|1000000|71428.57|62500|
|100000|1111111.11|1111111.11|57142.86|47619.05|
|1000000|840336.13|840336.13|61957.87|39682.54|
|10000000|711237.55|880281.69|59059.77|37181.63|

&ref(./dbm_hash.png,50%);

イメージとしては、hashなら、100万qps程度。dbmなら、7-3万qps程度だとイメージしておけば良い(他のdbm TokyoCabinetならもっと早いだろうが、デフォルトのdbmでもこのくらいの速度は出る)。

*** 自宅のVMWare上でのdbm,hashの速度調査 [#h4e0c891]
同様の調査を、VMWare上で行う。

母艦マシンは、iMac(WindowsXPを動かしている)。VMWare Server Ver2,動かしたOSは、ubuntu9.10である。

割り当てたメモリは、512MB,割り当てたCPU数は、1である。

|count|hash read(QPS)|hash write(QPS)|dbm read(QPS)|dbm write(QPS)|
|10000|1000000|1000000|100000|76923.08|
|100000|909090.91|1111111.11|71428.57|52910.05|
|1000000|862068.97|1041666.67|68681.32|45289.86|
|10000000|メモリ不足で実行できず|メモリ不足で実行できず|66657.78|38411.31|

&ref(./vmware_dbm_hash.png,50%);

こちらも同じく、hashだと、100万QPS程度、dbmだと、8万から、3万程度だと考えておけば良いだろう。
IOSTATを見ていて、EC2よりも、VMWare上のHDDの方が書き込みが少し、早いように感じた。

** おまけ、TokyoCabinetを試して見た。 [#l967c8ec]
[[Tokyo Cabinet:http://1978th.net/tokyocabinet/]]は、早いdbm見たいな物。

TokyoCabinetでのr/w性能の評価を、VMWare上で行う。特に、パラメータの調整を行っていない。

母艦マシンは、iMac(WindowsXPを動かしている)。VMWare Server Ver2,動かしたOSは、ubuntu9.10である。

割り当てたメモリは、512MB,割り当てたCPU数は、1である。

*** TokyoCabinetのPython Bindingの準備 [#e6195d3e]
ぐにゃらくんが、[[TokyoCabinetのPython Binding:http://pypi.python.org/pypi/pytc/]]を作ってくれている。

 sudo easy_install pytc
でインストール出来ます。

*** 計測 [#mc8d6e84]

|count|hash read(QPS)|hash write(QPS)|dbm read(QPS)|dbm write(QPS)|tc read(QPS)|tc write(QPS)|
|10000|1000000|早すぎて計測できず|125000|100000|1000000|500000|
|100000|909090.91|1111111.11|71942.45|55248.62|666666.67|909090.91|
|1000000|869565.22|1020408.16|68634.18|45475.22|581395.35|769230.77|
|10000000|メモリ不足で計測できず|メモリ不足で計測できず|67240.45|38660.79|273224.04|130718.95|

&ref(./dbm_tc.png,50%);

diskを使って、60万とか、70万とか出てきます。大体、dsbdbの10倍くらい出ている気がします。

** ソース類 [#x345e508]
計測に使ったソースは以下。python2.5以上で動くと思う。


&ref(./dbm_bench.py);

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS