Skip to content

Instantly share code, notes, and snippets.

@jedie
Created February 5, 2020 13:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jedie/1d658a184eb4435383820aa0c647d7e9 to your computer and use it in GitHub Desktop.
Save jedie/1d658a184eb4435383820aa0c647d7e9 to your computer and use it in GitHub Desktop.
Benchmark Django REST-Framework
import cProfile
import pstats
import time
from collections import OrderedDict, namedtuple
import django
import rest_framework
from django.conf import settings
from django.test import RequestFactory
from rest_framework.response import Response
settings.configure(
DEBUG=True,
INSTALLED_APPS=(
"django.contrib.contenttypes",
"django.contrib.auth",
"rest_framework",
)
)
django.setup()
from rest_framework import generics, serializers # noqa isort:skip
Entry = namedtuple('Entry', 'id name')
entries = [Entry(id=f'id{i}', name=f'Entry Name {i}') for i in range(1000)]
class EntrySerializer(serializers.Serializer):
id = serializers.CharField(max_length=200)
name = serializers.CharField(max_length=200)
class EntryViewSet(generics.ListCreateAPIView):
def list(self, request, *args, **kwargs):
serializer = EntrySerializer(entries, many=True)
return Response(serializer.data)
def benchmark():
print('Benchmark')
print(f'django v{django.__version__}')
print(f'REST framework v{rest_framework.__version__}')
view = EntryViewSet.as_view()
rf = RequestFactory()
request = rf.get('/')
start_time = time.monotonic()
response = view(request=request)
duration = time.monotonic() - start_time
print(f'takes: {duration*1000:.1f} ms')
# verify request/response:
assert response.status_code == 200
entries = response.data
assert len(entries) == 1000, len(entries)
assert entries[0] == OrderedDict(
[('id', 'id0'), ('name', 'Entry Name 0')]), entries[0]
assert entries[999] == OrderedDict(
[('id', 'id999'), ('name', 'Entry Name 999')]), entries[999]
print()
print('_' * 100)
print('run cProfile...\n')
pr = cProfile.Profile()
pr.enable()
view(request=request)
pr.disable()
pstats.Stats(pr).sort_stats('tottime', 'cumulative', 'calls').print_stats(20)
if __name__ == '__main__':
benchmark()
Benchmark
django v2.2.10
REST framework v3.11.0
takes: 8.2 ms
____________________________________________________________________________________________________
run cProfile...
47664 function calls (47653 primitive calls) in 0.014 seconds
Ordered by: internal time, cumulative time, call count
List reduced from 189 to 20 due to restriction <20>
ncalls tottime percall cumtime percall filename:lineno(function)
1000 0.002 0.000 0.013 0.000 /home/jens/.local/share/virtualenvs/foo-bar/lib/python3.6/site-packages/rest_framework/serializers.py:507(to_representation)
12036 0.002 0.000 0.003 0.000 {built-in method builtins.isinstance}
2000 0.001 0.000 0.003 0.000 /home/jens/.local/share/virtualenvs/foo-bar/lib/python3.6/site-packages/rest_framework/fields.py:59(is_simple_callable)
2000 0.001 0.000 0.002 0.000 /home/jens/.local/share/virtualenvs/foo-bar/lib/python3.6/abc.py:180(__instancecheck__)
2000 0.001 0.000 0.007 0.000 /home/jens/.local/share/virtualenvs/foo-bar/lib/python3.6/site-packages/rest_framework/fields.py:82(get_attribute)
3000 0.001 0.000 0.003 0.000 /home/jens/.local/share/virtualenvs/foo-bar/lib/python3.6/site-packages/rest_framework/serializers.py:373(_readable_fields)
3000 0.001 0.000 0.002 0.000 /home/jens/.local/share/virtualenvs/foo-bar/lib/python3.6/_collections_abc.py:760(__iter__)
4000 0.001 0.000 0.001 0.000 /home/jens/.local/share/virtualenvs/foo-bar/lib/python3.6/_weakrefset.py:70(__contains__)
2000 0.000 0.000 0.007 0.000 /home/jens/.local/share/virtualenvs/foo-bar/lib/python3.6/site-packages/rest_framework/fields.py:448(get_attribute)
2000 0.000 0.000 0.001 0.000 /usr/lib/python3.6/inspect.py:277(isbuiltin)
2000 0.000 0.000 0.001 0.000 /usr/lib/python3.6/inspect.py:159(isfunction)
2000 0.000 0.000 0.000 0.000 /usr/lib/python3.6/inspect.py:81(ismethod)
2000 0.000 0.000 0.000 0.000 /home/jens/.local/share/virtualenvs/foo-bar/lib/python3.6/site-packages/rest_framework/fields.py:841(to_representation)
1000 0.000 0.000 0.000 0.000 /home/jens/.local/share/virtualenvs/foo-bar/lib/python3.6/_collections_abc.py:680(values)
1 0.000 0.000 0.013 0.013 /home/jens/.local/share/virtualenvs/foo-bar/lib/python3.6/site-packages/rest_framework/serializers.py:678(<listcomp>)
2043/2042 0.000 0.000 0.000 0.000 {built-in method builtins.getattr}
1000 0.000 0.000 0.000 0.000 /home/jens/.local/share/virtualenvs/foo-bar/lib/python3.6/site-packages/rest_framework/utils/serializer_helpers.py:153(__iter__)
2000 0.000 0.000 0.000 0.000 /home/jens/.local/share/virtualenvs/foo-bar/lib/python3.6/site-packages/rest_framework/utils/serializer_helpers.py:147(__getitem__)
1001 0.000 0.000 0.000 0.000 {built-in method builtins.iter}
1000 0.000 0.000 0.000 0.000 /home/jens/.local/share/virtualenvs/foo-bar/lib/python3.6/_collections_abc.py:698(__init__)
@jedie
Copy link
Author

jedie commented Feb 5, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment