gae アプリ 開発メモ

Google App Engine アプリの開発メモ / 言語: python, javascript / ビギナー

sortedとDataStoreのorder()の速度を比べてみた

sorted()とDataStoreの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 RootHandler(webapp.RequestHandler):
    def get(self):
        output = StringIO.StringIO()

        times = 3
        self.in_memory_sort(output, times)
        self.datastore_sort(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>" % (10000000 * 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>" % (10000000 * 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()

結果


とりあえず 1000 件のソートを3回実行するようにしてみた。
実際のgaeの環境にデプロイして計測。
で、結果。

in_memory_sort = 1610.12014 usec/pass
datastore_sort = 2450133.16472 usec/pass

1500倍 sorted()の方が早い。
雲泥の差ってやつだな。

  • 『リストに結果を入れる』という操作を入れてる
  • そもそも扱っているオブジェクトが違う

といろいろ違いはあるので、単純に比較できるものでもないけど。

追記


関連記事: DataStoreのorder()のあり/なしで速度を比べてみた