Opened 3 years ago
Closed 3 years ago
#32945 closed Cleanup/optimization (invalid)
Improve performance of HttpRequest._current_scheme_host()
Reported by: | David Smith | Owned by: | nobody |
---|---|---|---|
Component: | HTTP handling | Version: | 3.2 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
_current_scheme_host()
currently uses .format
. I propose that we change this to an f-string
for a c.7.5% performance gain.
There's a few different ways this could be written, I think OptionTwo would be the one which would meet Django's f-string guidelines. I've shown a few different versions to show that moving to f-string is the big win here and adding a few extra variables (or not) as no impact.
One thing to note is that this function is decorated with cached_property
but I've removed this to benchmark the underlying function.
..................... Current: Mean +- std dev: 243 us +- 4 us ..................... Option One: Mean +- std dev: 226 us +- 2 us ..................... Option Two: Mean +- std dev: 225 us +- 3 us ..................... Option Three: Mean +- std dev: 226 us +- 2 us
import pyperf from django.conf import settings from django.http import HttpRequest import django settings.configure(ALLOWED_HOSTS = ['localhost']) django.setup() class CurrentHttpRequest(HttpRequest): def _current_scheme_host(self): return '{}://{}'.format(self.scheme, self.get_host()) class OptionOneHttpRequest(HttpRequest): def _current_scheme_host(self): return f'{self.scheme}://{self.get_host()}' class OptionTwoHttpRequest(HttpRequest): def _current_scheme_host(self): host = self.get_host() return f'{self.scheme}://{host}' class OptionThreeHttpRequest(HttpRequest): def _current_scheme_host(self): scheme = self.scheme host = self.get_host() return f'{scheme}://{host}' def current(loops): request = CurrentHttpRequest() request.META['SERVER_NAME'] = 'localhost' request.META['SERVER_PORT'] = '80' range_it = range(loops) t0 = pyperf.perf_counter() for loop in range_it: request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() return pyperf.perf_counter() - t0 def option_one(loops): request = OptionOneHttpRequest() request.META['SERVER_NAME'] = 'localhost' request.META['SERVER_PORT'] = '80' range_it = range(loops) t0 = pyperf.perf_counter() for loop in range_it: request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() return pyperf.perf_counter() - t0 def option_two(loops): request = OptionTwoHttpRequest() request.META['SERVER_NAME'] = 'localhost' request.META['SERVER_PORT'] = '80' range_it = range(loops) t0 = pyperf.perf_counter() for loop in range_it: request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() return pyperf.perf_counter() - t0 def option_three(loops): request = OptionThreeHttpRequest() request.META['SERVER_NAME'] = 'localhost' request.META['SERVER_PORT'] = '80' range_it = range(loops) t0 = pyperf.perf_counter() for loop in range_it: request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() request._current_scheme_host() return pyperf.perf_counter() - t0 runner = pyperf.Runner() runner.bench_time_func('Current', current) runner.bench_time_func('Option One', option_one) runner.bench_time_func('Option Two', option_two) runner.bench_time_func('Option Three', option_three)
Change History (1)
comment:1 by , 3 years ago
Component: | Uncategorized → HTTP handling |
---|---|
Resolution: | → invalid |
Status: | new → closed |
Type: | Uncategorized → Cleanup/optimization |
Thanks for this proposition, however I don't think it's worth changing. I don't see a significant improvement in Python 3.8:
and in Python 3.10 is even worse: