#32782: Optimize _get_user_permissions by using set comprehensions
-------------------------------------+-------------------------------------
Reporter: Abhyudai | Owner: nobody
Type: | Status: closed
Cleanup/optimization |
Component: Uncategorized | Version: 3.2
Severity: Normal | Resolution: needsinfo
Keywords: permissions, auth | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Nick Pope):
I thought an alternative implementation could be the following to avoid
needing `hasattr()` and `getattr()`:
{{{#!python
def _user_get_permissions(user, obj, name):
name = f'get_{name}_permissions'
return {
permission
for backend in auth.get_backends()
if (method := getattr(backend, name, None))
for permission in method(user, obj)
}
}}}
I think this is more readable (personally), but there is no speed up:
{{{
Before: Mean +- std dev: 252 us +- 16 us
After: Mean +- std dev: 253 us +- 10 us
}}}
Maybe I got something wrong in my script. Here it is if anyone was
interested in how to do this:
{{{#!python
import time
import django
import pyperf
from django.apps import apps
from django.conf import settings
from django.core.management import call_command
settings.configure(
# Duplicate default backend 10 times to add more looping:
AUTHENTICATION_BACKENDS=['django.contrib.auth.backends.ModelBackend']
* 10,
DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME':
':memory:'}},
INSTALLED_APPS=['django.contrib.auth', 'django.contrib.contenttypes',
'__main__'],
)
django.setup()
# Run the migrations to create the require models:
call_command('migrate', verbosity=0)
# Look up the required models:
User = apps.get_model('auth.User')
Group = apps.get_model('auth.Group')
Permission = apps.get_model('auth.Permission')
# Create a user with a group and permissions assigned to both the user and
group:
user = User.objects.create_user('test')
group = Group.objects.create(name='test')
permissions = Permission.objects.all()
user.groups.add(group)
user.user_permissions.add(*permissions)
group.permissions.add(*permissions)
# Call permission methods to pre-cache results to reduce overhead from
database queries:
user.get_all_permissions()
user.get_user_permissions()
user.get_group_permissions()
def test(loops, user):
range_it = range(loops)
t0 = time.perf_counter()
for loop in range_it:
user.get_all_permissions()
user.get_user_permissions()
user.get_group_permissions()
return time.perf_counter() - t0
runner = pyperf.Runner()
runner.bench_time_func('Fetch Permissions', test, user)
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/32782#comment:3>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/068.986c5dd332ad399111c31f68a1c8db2e%40djangoproject.com.