【发布时间】:2011-01-18 23:19:36
【问题描述】:
目前我的应用程序在 memcache 中缓存模型,如下所示:
memcache.set("somekey", aModel)
但 Nicks 在 http://blog.notdot.net/2009/9/Efficient-model-memcaching 的帖子表明,首先将其转换为 protobuffers 会更有效。但在运行了一些测试后,我发现它的尺寸确实更小,但实际上更慢 (~10%)。
其他人有同样的经历还是我做错了什么?
测试结果:http://1.latest.sofatest.appspot.com/?times=1000
import pickle
import time
import uuid
from google.appengine.ext import webapp
from google.appengine.ext import db
from google.appengine.ext.webapp import util
from google.appengine.datastore import entity_pb
from google.appengine.api import memcache
class Person(db.Model):
name = db.StringProperty()
times = 10000
class MainHandler(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
m = Person(name='Koen Bok')
t1 = time.time()
for i in xrange(int(self.request.get('times', 1))):
key = uuid.uuid4().hex
memcache.set(key, m)
r = memcache.get(key)
self.response.out.write('Pickle took: %.2f' % (time.time() - t1))
t1 = time.time()
for i in xrange(int(self.request.get('times', 1))):
key = uuid.uuid4().hex
memcache.set(key, db.model_to_protobuf(m).Encode())
r = db.model_from_protobuf(entity_pb.EntityProto(memcache.get(key)))
self.response.out.write('Proto took: %.2f' % (time.time() - t1))
def main():
application = webapp.WSGIApplication([('/', MainHandler)], debug=True)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
【问题讨论】:
-
我也只是尝试了非常大且复杂的模型,但结果大致相同。
-
GAE 上可能有docs.python.org/library/timeit.html?这应该会显示更准确的结果,但仍然 - 在阅读了您链接到的博客文章后,我预计 protobuffers 和 pickle 的性能之间存在数量级差异 - 无论如何这应该被 time.time() 捕获..
-
我正在使用 java appengine,所以我懒得测试这个理论——pickle() 是否在某处缓存了幕后的结果,而 to_protobuf 不是?根据这篇文章,我不确定我是否会期望速度会提高一个数量级,因为即使使用 protobuf 版本,仍然会调用 pickle。不过,使用的空间肯定会小得多。
-
我做了更多的测试,memcache 只腌制非字符串,所以存储单个模型根本不会腌制,模型列表将被腌制为带有字符串的列表。
-
这无疑是一个令人惊讶的结果。我会说这是一个 dev_appserver 现象,但你在 apppot 上看到了相同的结果。让我感到困惑 - 这当然不是过去的情况。
标签: google-app-engine memcached google-cloud-datastore