Skip to content

Instantly share code, notes, and snippets.

@hirokazumiyaji
Created May 7, 2014 10:18
Show Gist options
  • Save hirokazumiyaji/f25a1048380304651f84 to your computer and use it in GitHub Desktop.
Save hirokazumiyaji/f25a1048380304651f84 to your computer and use it in GitHub Desktop.
Djangoでgeventを使用する場合と使用しない場合の比較してみる。
# coding: utf-8
from __future__ import absolute_import, unicode_literals
import gevent
from django.db import models
from django.utils.functional import cached_property
class AppUser(models.Model):
id = models.CharField(max_length=100, primary_key=True)
name = models.CharField(max_length=100)
@classmethod
def get(cls, id):
return cls.objects.get(id=id)
@cached_property
def sum_app_data(self):
return sum([AppUserData.get_value(self.id, category) for category in APP_USER_DATA_CATEGORIES])
@cached_property
def gevent_sum_app_data(self):
threads = [gevent.spawn(AppUserData.get_value, self.id, category)
for category in APP_USER_DATA_CATEGORIES]
gevent.joinall(threads)
return sum([thread.value for thread in threads])
APP_USER_DATA_CATEGORIES = range(1000)
class AppUserData(models.Model):
user_id = models.CharField(max_length=100, db_index=True)
category = models.IntegerField(default=0)
value = models.IntegerField(default=0)
@classmethod
def get_value(cls, user_id, category):
try:
app_user_data = cls.objects.get(user_id=user_id, category=category)
return app_user_data.value
except cls.DoesNotExist:
return 0
# coding: utf-8
from __future__ import absolute_import, unicode_literals
from django.db import models
from django.utils.functional import cached_property
class Group(models.Model):
name = models.CharField(max_length=100)
@cached_property
def members(self):
return GroupMember.filter_by_group(self.id)
class GroupMember(models.Model):
group_id = models.IntegerField(db_index=True)
user_id = models.CharField(max_length=100, db_index=True)
@cached_property
def user(self):
from ..appuser.models import AppUser
return AppUser.get(self.user_id)
@classmethod
def filter_by_group(cls, group_id):
return list(cls.objects.filter(group_id=group_id))
# coding: utf-8
from __future__ import absolute_import, unicode_literals
import time
import random
from operator import attrgetter
import gevent
from django.db import connection
from django.test import TestCase
from ..group.models import Group, GroupMember
from .models import AppUser, AppUserData, APP_USER_DATA_CATEGORIES
def calc(member):
return (member.user.sum_app_data, member)
class ApplicationTest(TestCase):
def setUp(self):
app_users = []
app_users_data = []
for user_id in range(1000, 1101):
app_users.append(
AppUser(id=str(user_id), name="name:{}".format(user_id)))
for category in APP_USER_DATA_CATEGORIES:
app_users_data.append(AppUserData(
user_id=str(user_id), category=category, value=random.randint(100, 100000)))
AppUser.objects.bulk_create(app_users)
AppUserData.objects.bulk_create(app_users_data)
for i in range(1, len(app_users) / 25 + 1):
group = Group.objects.create(name="group:{}".format(i))
members = [GroupMember(group_id=group.id, user_id=user.id)
for user in app_users[i * 25: i * 25 + 25]]
GroupMember.objects.bulk_create(members)
def tearDown(self):
AppUser.objects.all().delete()
AppUserData.objects.all().delete()
def main(self):
group = Group.objects.get(id=1)
start = time.time()
sorted(group.members, key=attrgetter("user.gevent_sum_app_data"))
print "end ..... {}".format(time.time() - start)
def gevent_main(self):
group = Group.objects.get(id=1)
start = time.time()
threads = [gevent.spawn(calc, member) for member in group.members]
gevent.joinall(threads)
print "join ..... {}".format(time.time() - start)
members = [member[1] for member in sorted(
[thread.value for thread in threads], key=lambda x: x[0])]
print "end ..... {}".format(time.time() - start)
not gevent : 44.7652320862s
gevent: 44.1778178215
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment