風柳メモ

ソフトウェア・プログラミング関連の覚書が中心

GAEのmemcacheでlist等を読み書きすると予想外にコストがかかる

Google App Engine/Pythonのmemcacheはtupleやdictやobject、それらのlistなんかも読み書き出来るので手軽なのだが、単純なstringなんかを読み書きする場合と比較すると、思ったよりもコストがかかるようなので、覚書。

テスト

from google.appengine.api import memcache
from google.appengine.api import quota
from django.utils import simplejson
from array import array

test_str = 'A'*100000
test_list = array('c',test_str).tolist()

のようにして用意したstringとlistをmemcacheで書き込み/読み出しして、quota.get_request_cpu_usage()で要したCPU時間(megacycles)を比較。

1. string
# 書き込み
memcache.set(key='test_str',value=test_str,time=60)

# 読み出し
test_str = memcache.get(key='test_str')
2. list
# 書き込み
memcache.set(key='test_list',value=test_list,time=60)

# 読み出し
test_list = memcache.get(key='test_list')
3. listを','で結合(string化)/分割(復元)
# 書き込み
join_list=','.join(test_list)
memcache.set(key='join_list',value=join_list,time=60)

# 読み出し
join_list = memcache.get(key='join_list')
test_list = join_list.split(',')
4. listをsimplejsonでstring化/復元
# 書き込み
json_list=simplejson.dumps(test_list,separators=(',',':'))
memcache.set(key='json_list',value=json_list,time=60)

# 読み出し
json_list = memcache.get(key='json_list')
test_list = simplejson.loads(json_list)

結果

1. string2. list3. join()/split()4. simplejson
書き込み27147984
読み出し2392124044
※書き込み(set)/読み出し(get)の値はmegacycles

  • 文字列(string)の読み書きに比べてlistの読み書きは結構遅くなってしまう。
  • 単純な構造であればフォーマットを決めて(上記例では','区切り)一度文字列化(同join())してから書き込み、読み出し後に復元(同split())した方がよい。
  • そうかといって、simplejsonを用いて文字列化/復元すると、そっちのオーバヘッドの方が大きくなってしまう。