encode / django-rest-framework

Web APIs for Django. 🎸
https://www.django-rest-framework.org
Other
28.51k stars 6.85k forks source link

[Performance] Views with and without authentication differs a lot in performance #4327

Closed fengyehong closed 8 years ago

fengyehong commented 8 years ago

Steps to reproduce

  1. Set up the tutorial project, and set debug to Fase
  2. Use gunicorn as webserver: gunicorn -b 0.0.0.0:8000 -w 5 tutorial.wsgi
  3. Use Apache benchmarking tool to test: ab -c 10 -n 1000 -A root:pass123 http://localhost:8000/users/
Server Software:        gunicorn/19.4.1
Server Hostname:        localhost
Server Port:            8000

Document Path:          /users/
Document Length:        83 bytes

Concurrency Level:      10
Time taken for tests:   9.027 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      299000 bytes
HTML transferred:       83000 bytes
Requests per second:    110.78 [#/sec] (mean)
Time per request:       90.273 [ms] (mean)
Time per request:       9.027 [ms] (mean, across all concurrent requests)
Transfer rate:          32.35 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:    37   89  30.6     86     350
Waiting:       37   89  30.3     86     350
Total:         37   89  30.6     86     350

Percentage of the requests served within a certain time (ms)
  50%     86
  66%     96
  75%    105
  80%    111
  90%    121
  95%    136
  98%    155
  99%    170
 100%    350 (longest request)

It seems, with this simplest app, we can only process 110.78 requests per second

4.But if i disable authentication on this viewset, i get a performance boost

class UserViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows users to be viewed or edited.
    """
    queryset = User.objects.all().order_by('-date_joined')
    serializer_class = UserSerializer

    authentication_classes = ()
    permission_classes = ()

5.Benchmarking result:

Server Software:        gunicorn/19.4.1
Server Hostname:        localhost
Server Port:            8000

Document Path:          /users/
Document Length:        83 bytes

Concurrency Level:      10
Time taken for tests:   1.571 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      291000 bytes
HTML transferred:       83000 bytes
Requests per second:    636.36 [#/sec] (mean)
Time per request:       15.714 [ms] (mean)
Time per request:       1.571 [ms] (mean, across all concurrent requests)
Transfer rate:          180.84 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       1
Processing:     5   15  13.8     12     163
Waiting:        5   15  13.8     11     163
Total:          5   15  13.8     12     163

Percentage of the requests served within a certain time (ms)
  50%     12
  66%     15
  75%     17
  80%     18
  90%     23
  95%     31
  98%     49
  99%     69
 100%    163 (longest request)

Look at the difference:

Requests per second:    110.78 [#/sec] (mean)
Requests per second:    636.36 [#/sec] (mean)

Here is my question:

  1. why 'authentication took so much time' ?
  2. how can i achieve better performance with basic authentication on my views ?
  3. or did I make something wrong ?

THX

Test environment: drf: 3.4.0 django: 1.8.12 python: 2.7 OS: centos 7, 4core

And I tried with mysql as database, got the same result.

attached my test project: tutorial.tar.gz

xordoquy commented 8 years ago

The discussion group is the best place to take this discussion and other usage questions. Thanks!

Deenbandhu-agarwal-ua commented 1 year ago

@fengyehong were we able to solve this

Igonato commented 1 year ago

@Deenbandhu-agarwal-ua OP uses basic authentication, which will result in the password hash calculation on every request. Password hashing is computationally intensive by design. I bet that's the reason for the slowdown. To confirm - run the test with token or session auth.