Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions benchmarks/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ class TestModel(models.Model):


class DirectUser(UserObjectPermissionBase):
content_object = models.ForeignKey('TestDirectModel', on_delete=models.CASCADE)
content_object = models.ForeignKey("TestDirectModel", on_delete=models.CASCADE)


class DirectGroup(GroupObjectPermissionBase):
content_object = models.ForeignKey('TestDirectModel', on_delete=models.CASCADE)
content_object = models.ForeignKey("TestDirectModel", on_delete=models.CASCADE)


class TestDirectModel(models.Model):
Expand Down
99 changes: 63 additions & 36 deletions benchmarks/run_benchmarks.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@
abspath = lambda *p: os.path.abspath(os.path.join(*p))

THIS_DIR = abspath(os.path.dirname(__file__))
ROOT_DIR = abspath(THIS_DIR, '..')
ROOT_DIR = abspath(THIS_DIR, "..")

# so the preferred guardian module is one within this repo and
# not system-wide
sys.path.insert(0, ROOT_DIR)

os.environ["DJANGO_SETTINGS_MODULE"] = 'benchmarks.settings'
os.environ["DJANGO_SETTINGS_MODULE"] = "benchmarks.settings"

import django

django.setup()

from benchmarks import settings
Expand All @@ -40,11 +41,10 @@


def random_string(length=25, chars=string.ascii_letters + string.digits):
return ''.join(random.choice(chars) for i in range(length))
return "".join(random.choice(chars) for i in range(length))


class Call:

def __init__(self, args, kwargs, start=None, finish=None):
self.args = args
self.kwargs = kwargs
Expand All @@ -56,13 +56,12 @@ def delta(self):


class Timed:

def __init__(self, action=None):
self.action = action

def __call__(self, func):

if not hasattr(func, 'calls'):
if not hasattr(func, "calls"):
func.calls = []

def wrapper(*args, **kwargs):
Expand All @@ -76,44 +75,58 @@ def wrapper(*args, **kwargs):
call.finish = datetime.datetime.now()
func.calls.append(call)
if self.action:
print(" -> [{}] Done (Total time: {})".format(self.action,
call.delta()))
print(
" -> [{}] Done (Total time: {})".format(
self.action, call.delta()
)
)

return wrapper


class Benchmark:

def __init__(self, name, users_count, objects_count,
objects_with_perms_count, model, subquery):
def __init__(
self,
name,
users_count,
objects_count,
objects_with_perms_count,
model,
subquery,
):
self.name = name
self.users_count = users_count
self.objects_count = objects_count
self.objects_with_perms_count = objects_with_perms_count
self.subquery = subquery
self.Model = model
self.perm = 'add_%s' % model._meta.model_name
self.perm = "add_%s" % model._meta.model_name

def info(self, msg):
print(colorize(msg + '\n', fg='green'))
print(colorize(msg + "\n", fg="green"))

def prepare_db(self):
from django.core.management import call_command
call_command('makemigrations', interactive=False)
call_command('migrate', interactive=False)

call_command("makemigrations", interactive=False)
call_command("migrate", interactive=False)

for model in [User, Group, self.Model]:
model.objects.all().delete()

@Timed("Creating users")
def create_users(self):
User.objects.bulk_create(User(id=x, username=random_string().capitalize())
for x in range(self.users_count))
User.objects.bulk_create(
User(id=x, username=random_string().capitalize())
for x in range(self.users_count)
)

@Timed("Creating objects")
def create_objects(self):
Model = self.Model
Model.objects.bulk_create(Model(id=x, name=random_string(20))
for x in range(self.objects_count))
Model.objects.bulk_create(
Model(id=x, name=random_string(20)) for x in range(self.objects_count)
)

@Timed("Grant permissions")
def grant_perms(self):
Expand All @@ -140,10 +153,11 @@ def get_objects(self):
ids = range(1, self.users_count)
for user in User.objects.iterator():
for x in xrange(self.objects_with_perms_count):
filters = {'user': random.choice(ids),
'permission__codename__in': [self.perm],
'content_type': ctype
}
filters = {
"user": random.choice(ids),
"permission__codename__in": [self.perm],
"content_type": ctype,
}
qs = UserObjectPermission.objects.filter(**filters).all()
if not self.subquery:
qs = [v.object_pk for v in qs]
Expand All @@ -154,9 +168,9 @@ def check_perm(self, user, obj, perm):

@Timed("Benchmark")
def main(self):
self.info('=' * 80)
self.info("=" * 80)
self.info(self.name.center(80))
self.info('=' * 80)
self.info("=" * 80)
self.prepare_db()
self.create_users()
self.create_objects()
Expand All @@ -167,16 +181,29 @@ def main(self):


def main():
show_settings(settings, 'benchmarks')
show_settings(settings, "benchmarks")
glob = [USERS_COUNT, OBJECTS_COUNT, OBJECTS_WIHT_PERMS_COUNT]
Benchmark('Direct relations benchmark with subqueries', *glob,
model=TestDirectModel, subquery=True).main()

Benchmark('Direct relations benchmark without subqueries', *glob,
model=TestDirectModel, subquery=False).main()

Benchmark('Generic relations benchmark without subqueries', *glob,
model=TestModel, subquery=False).main()

if __name__ == '__main__':
Benchmark(
"Direct relations benchmark with subqueries",
*glob,
model=TestDirectModel,
subquery=True
).main()

Benchmark(
"Direct relations benchmark without subqueries",
*glob,
model=TestDirectModel,
subquery=False
).main()

Benchmark(
"Generic relations benchmark without subqueries",
*glob,
model=TestModel,
subquery=False
).main()


if __name__ == "__main__":
main()
20 changes: 10 additions & 10 deletions benchmarks/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@
abspath = lambda *p: os.path.abspath(os.path.join(*p))

THIS_DIR = abspath(os.path.dirname(__file__))
ROOT_DIR = abspath(THIS_DIR, '..')
ROOT_DIR = abspath(THIS_DIR, "..")

# so the preferred guardian module is one within this repo and
# not system-wide
sys.path.insert(0, ROOT_DIR)

SECRET_KEY = 'NO_NEED_SECRET'
SECRET_KEY = "NO_NEED_SECRET"

INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.sessions',
'django.contrib.contenttypes',
'django.contrib.admin',
'django.contrib.sites',
'guardian',
'benchmarks',
"django.contrib.auth",
"django.contrib.sessions",
"django.contrib.contenttypes",
"django.contrib.admin",
"django.contrib.sites",
"guardian",
"benchmarks",
)

DJALOG_LEVEL = 40

DATABASES = {'default': env.db(default="sqlite:///")}
DATABASES = {"default": env.db(default="sqlite:///")}
Loading