Web サービス (DynamoDB) にアクセスする Python アプリケーションがあります。15,000 回の POST 操作を実行しますが、1 秒あたり 1,000 回に制限されています。
ログを追加した後、各 POST の前に常に同じ情報を返すリソースの更新があることに気付きました。
ログは次のようになります。
DynamoDB_20111205.DescribeTable: id=... time=27ms
DynamoDB_20111205.PutItem: id=... time=22ms
DynamoDB_20111205.DescribeTable: id=... time=27ms
DynamoDB_20111205.PutItem: id=... time=22ms
DynamoDB_20111205.DescribeTable: id=... time=27ms
DynamoDB_20111205.PutItem: id=... time=22ms
DynamoDB_20111205.DescribeTable: id=... time=27ms
DynamoDB_20111205.PutItem: id=... time=22ms
対予想:
DynamoDB_20111205.DescribeTable: id=... time=27ms
DynamoDB_20111205.PutItem: id=... time=22ms
DynamoDB_20111205.PutItem: id=... time=22ms
DynamoDB_20111205.PutItem: id=... time=22ms
DynamoDB_20111205.PutItem: id=... time=22ms
もちろん、私の反応は、「DescribeTable」操作の結果をキャッシュすることでした。これは、(私が気にしないいくつかのビットを除いて) 常に同じであり、パフォーマンスの「向上」に興味があったからです。私のテストの大きさの順序は次のとおりです。
- キャッシュなし: 37.5 秒
- クラス レベルキャッシュ: 41.8 秒 (すべてのインスタンスで共有)
- インスタンス レベルのキャッシュ: 41.7 秒
私は同様の条件下でそれぞれ6回繰り返しましたが、「科学的品質」の測定は一切試みませんでした.
編集:これは私のコードの簡素化されたバージョンです。これは非常に単純化されています。実際のバージョンでは、リリースされていないバージョンの Boto、DynamoDB-mapper、および gevent の greenlets を使用しています。
#!/usr/bin/env python
class RemoteTableInfo(objects):
def __init__(self):
load_remote_table_info() # Triggers the "DescribeTable" in logs
class Item(objects):
def save(self, table, ...):
do_some_IO() # Triggers the "PutItem" in logs
class ObjectMapper_with_cache(object):
table = None
def __init__(self):
cls = type(self)
if cls.table is None:
self.table = RemoteTableInfo()
def do_work(self):
cls = type(self)
Item(cls.table, ...).save()
class ObjectMapper_no_cache(object):
def do_work(self):
table = RemoteTableInfo()
Item(table, ...).save()
# Slow version
for i in range(15000):
ObjectMapper_with_cache().do_work()
# Fast version
for i in range(15000):
ObjectMapper_no_cache().do_work()
私の「最も賢い」試行 (クラス レベル) で、キャッシュのないバージョンが4秒速くなるのはなぜですか?
注: これは Python の内部構造に関連していて、基盤となるフレームワークに関連しているとは思えません。