DataStoreのorder()のあり/なしで速度を比べてみた
sortedとDataStoreのorder()の速度を比べてみたでは、order()しない読み取り速度を計測していなかった。
そんな調査結果で開発方針を判断しちゃマズいかな、と思い再度計測。
ソース
#!/usr/bin/env python # -*- coding: utf-8 -*- from google.appengine.ext import webapp from google.appengine.ext import db from google.appengine.ext.webapp import util import StringIO import timeit import random class Person(db.Model): name = db.StringProperty(required=True, indexed=False) age = db.IntegerProperty(required=True, indexed=True) class Person2(db.Model): name = db.StringProperty(required=True, indexed=False) age = db.IntegerProperty(required=True, indexed=False) class RootHandler(webapp.RequestHandler): def get(self): output = StringIO.StringIO() times = 3 self.in_memory_sort(output, times) self.datastore_sort(output, times) self.datastore(output, times) self.response.out.write(output.getvalue()) output.close() def in_memory_sort(self, output, times): t = timeit.Timer( setup = """ import random persons = {} for n in range(1000): persons['item' + str(n)] = { 'name': 'name' + str(n), 'age': random.randint(1, 80) } """, stmt = """ result = sorted(persons.itervalues(), key = lambda person: person['age']) """ ) output.write("in_memory_sort = %.5f usec/pass<br>" % (1000000 * min(t.repeat(repeat = times, number=1)) / times)) def datastore_sort(self, output, times): # データを一旦消去 keys = Person.all(keys_only = True) db.delete(keys) persons = [] for n in range(1000): persons.append(Person(name = 'name' + str(n), age = random.randint(1, 80))) db.put(persons) t = timeit.Timer( setup = """ from google.appengine.ext import db class Person(db.Model): name = db.StringProperty(required=True, indexed=False) age = db.IntegerProperty(required=True, indexed=True) """, stmt = """ persons = Person.all().order('age') result = [person for person in persons] """ ) output.write("datastore_sort = %.5f usec/pass<br>" % (1000000 * min(t.repeat(repeat = times, number=1)) / times)) def datastore(self, output, times): # データを一旦消去 keys = Person2.all(keys_only = True) db.delete(keys) persons = [] for n in range(1000): persons.append(Person2(name = 'name' + str(n), age = random.randint(1, 80))) db.put(persons) t = timeit.Timer( setup = """ from google.appengine.ext import db class Person2(db.Model): name = db.StringProperty(required=True, indexed=False) age = db.IntegerProperty(required=True, indexed=False) """, stmt = """ persons = Person2.all() result = [person for person in persons] """ ) output.write("datastore = %.5f usec/pass<br>" % (1000000 * min(t.repeat(repeat = times, number=1)) / times)) def main(): global request_handlers application = webapp.WSGIApplication([('/', RootHandler)], debug=True) util.run_wsgi_app(application) if __name__ == '__main__': main()
結果
# 1回目 in_memory_sort = 160.46158 usec/pass datastore_sort = 153,583.24278 usec/pass datastore = 155,220.48863 usec/pass # 2回目 in_memory_sort = 160.33937 usec/pass datastore_sort = 153,148.05337 usec/pass datastore = 151,476.71095 usec/pass
うーん。
order()なしの速度が安定しないけど、要するに共に150msec/1000件くらいで大差がないってことみたい。
で、sorted()の実行速度はDataStoreのやりとりに比べれば、無視できるものと解釈していいのかな。
ということは
- DataStoreとのやりとりは最小に。
- DataStoreにはソート目的のインデックスはWriteOpsを増加させるだけのメリットがない
ってことだな。
これだけでも収穫。