[Django] #32945: Improve performance of HttpRequest._current_scheme_host()

17 views
Skip to first unread message

Django

unread,
Jul 19, 2021, 4:16:23 PM7/19/21
to django-...@googlegroups.com
#32945: Improve performance of HttpRequest._current_scheme_host()
-----------------------------------------+------------------------
Reporter: David Smith | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 3.2
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+------------------------
`_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)

}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/32945>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Jul 20, 2021, 12:55:06 AM7/20/21
to django-...@googlegroups.com
#32945: Improve performance of HttpRequest._current_scheme_host()
-------------------------------------+-------------------------------------

Reporter: David Smith | Owner: nobody
Type: | Status: closed
Cleanup/optimization |
Component: HTTP handling | Version: 3.2
Severity: Normal | Resolution: invalid

Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* status: new => closed
* resolution: => invalid
* component: Uncategorized => HTTP handling
* type: Uncategorized => Cleanup/optimization


Comment:

Thanks for this proposition, however I don't think it's worth changing. I
don't see a significant improvement in Python 3.8:
{{{
.....................
Current: Mean +- std dev: 29.4 us +- 1.9 us
.....................
Option One: Mean +- std dev: 28.9 us +- 0.7 us
.....................
Option Two: Mean +- std dev: 28.9 us +- 0.7 us
.....................
Option Three: Mean +- std dev: 29.2 us +- 1.5 us
}}}
and in Python 3.10 is even worse:
{{{
.....................
Current: Mean +- std dev: 34.4 us +- 1.2 us
.....................
Option One: Mean +- std dev: 34.2 us +- 0.9 us
.....................
Option Two: Mean +- std dev: 34.7 us +- 0.9 us
.....................
Option Three: Mean +- std dev: 34.8 us +- 0.9 us
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/32945#comment:1>

Reply all
Reply to author
Forward
0 new messages