#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 Abhyudai):
I also didn't notice any speed up even without the `:=` walrus operator
and `f-strings`(using my original patch). My results were pretty similar
to the ones observed by Nick.
Although, the non-scientific benchmarking was encouraging (using `time`
command), the more scientific one wasn't.
For what it is worth, the script user for benchmarking was
{{{#!python
import os
from django.conf.global_settings import INSTALLED_APPS
import django
from django.conf import settings
from django.core.management import call_command
import pyperf
settings.configure(
INSTALLED_APPS= (
'django.contrib.auth',
'django.contrib.contenttypes',
),
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
'db.sqlite3'
),
}
},
)
django.setup()
call_command('migrate', verbosity=0)
from django.contrib.auth.models import User, _user_get_permissions
user, _ = User.objects.get_or_create(username='a', password='a')
def test(loops):
t0 = pyperf.perf_counter()
# repeat to reduce impact of for loop
for loop in range(loops):
_user_get_permissions(user, None, 'all')
_user_get_permissions(user, None, 'all')
_user_get_permissions(user, None, 'all')
_user_get_permissions(user, None, 'all')
_user_get_permissions(user, None, 'all')
_user_get_permissions(user, None, 'all')
_user_get_permissions(user, None, 'all')
_user_get_permissions(user, None, 'all')
_user_get_permissions(user, None, 'all')
_user_get_permissions(user, None, 'all')
_user_get_permissions(user, None, 'all')
return pyperf.perf_counter() - t0
runner = pyperf.Runner()
runner.bench_time_func('User permissions', test)
}}}
{{{
Before: Mean +- std dev: 220 us +- 11 us
After: User permissions: Mean +- std dev: 223 us +- 11 us
}}}
This appeared a lit weird to me because comprehensions tend to be
computationally faster than the traditional `for` loops. At least, that is
how they are marketed, and were sold to me :-p
The script used for profiling was,(this was saved as `profiler.py`)
{{{#!python
import os
from django.conf.global_settings import INSTALLED_APPS
import django
from django.conf import settings
from django.core.management import call_command
settings.configure(
INSTALLED_APPS= (
'django.contrib.auth',
'django.contrib.contenttypes',
),
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
'db.sqlite3'
),
}
},
)
django.setup()
from django.contrib.auth.models import User, _user_get_permissions
user, _ = User.objects.get_or_create(username='a', password='a')
def main():
user.get_all_permissions()
if __name__ == '__main__':
main()
}}}
I saw a tiny increase in the percentage of time spent in the
`_user_get_permissions` function. The earlier one took `1.29%`, while the
newer one spent `1.31%`, although pretty insignificant but the traditional
`for` loops one spends lesser time !
I can't seem to find a way to attach the `pstats` files here.
--
Ticket URL: <https://code.djangoproject.com/ticket/32782#comment:4>
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.08016f21635a31096dd3ad99daa50bec%40djangoproject.com.