test(bench): Add Django benchmark (#1087)
* test(bench): Add Django benchmark * chore: Fix pep8 in django app
This commit is contained in:
parent
b51d4e9a35
commit
cf011c7c8f
|
@ -254,11 +254,12 @@ def run(frameworks, trials, iterations, stat_memory):
|
|||
def main():
|
||||
frameworks = [
|
||||
'bottle',
|
||||
'django',
|
||||
'falcon',
|
||||
'falcon-ext',
|
||||
'flask',
|
||||
'pecan',
|
||||
'werkzeug'
|
||||
'werkzeug',
|
||||
]
|
||||
|
||||
parser = argparse.ArgumentParser(description='Falcon benchmark runner')
|
||||
|
@ -313,7 +314,7 @@ def main():
|
|||
us_per_req = (sec_per_req * Decimal(10 ** 6))
|
||||
factor = round_to_int(baseline / sec_per_req)
|
||||
|
||||
print('{3}. {0:.<15s}{1:.>06d} req/sec or {2: >3.2f} μs/req ({4}x)'.
|
||||
print('{3}. {0:.<20s}{1:.>06d} req/sec or {2: >3.2f} μs/req ({4}x)'.
|
||||
format(name, req_per_sec, us_per_req, i + 1, factor))
|
||||
|
||||
if heapy and args.stat_memory:
|
||||
|
|
|
@ -96,59 +96,26 @@ def werkzeug(body, headers):
|
|||
return hello
|
||||
|
||||
|
||||
def cherrypy(body, headers):
|
||||
import cherrypy
|
||||
|
||||
# Disable logging
|
||||
cherrypy.config.update({'environment': 'embedded'})
|
||||
|
||||
class HelloResource(object):
|
||||
|
||||
exposed = True
|
||||
|
||||
def GET(self, account_id, test, limit=8):
|
||||
user_agent = cherrypy.request.headers['User-Agent'] # NOQA
|
||||
for name, value in headers.items():
|
||||
cherrypy.response.headers[name] = value
|
||||
|
||||
return body
|
||||
|
||||
class Root(object):
|
||||
pass
|
||||
|
||||
root = Root()
|
||||
root.hello = HelloResource()
|
||||
|
||||
conf = {
|
||||
'/': {
|
||||
'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
|
||||
}
|
||||
}
|
||||
|
||||
app = cherrypy.tree.mount(root, '/', conf)
|
||||
return app
|
||||
|
||||
|
||||
# def wsme(body, headers):
|
||||
# import wsme
|
||||
|
||||
# class HelloService(wsme.WSRoot):
|
||||
|
||||
# @wsme.expose(str, str)
|
||||
# def hello(self, limit='10'):
|
||||
# import pdb
|
||||
# pdb.set_trace()
|
||||
# return body
|
||||
|
||||
# ws = HelloService(protocols=['restjson'])
|
||||
# return ws.wsgiapp()
|
||||
|
||||
|
||||
def pecan(body, headers):
|
||||
import falcon.bench.nuts.nuts.app as nuts
|
||||
import pecan
|
||||
pecan.x_test_body = body
|
||||
pecan.x_test_headers = headers
|
||||
|
||||
import falcon.bench.nuts.nuts.app as nuts
|
||||
sys.path.append(os.path.dirname(nuts.__file__))
|
||||
app = nuts.create()
|
||||
del sys.path[-1]
|
||||
|
||||
return app
|
||||
|
||||
|
||||
def django(body, headers):
|
||||
import django
|
||||
django.x_test_body = body
|
||||
django.x_test_headers = headers
|
||||
|
||||
from falcon.bench import dj
|
||||
sys.path.append(os.path.dirname(dj.__file__))
|
||||
|
||||
from falcon.bench.dj.dj import wsgi
|
||||
return wsgi.application
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
"""
|
||||
Django settings for dj project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 1.11.3.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/1.11/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/1.11/ref/settings/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = 't6gj%z0ee)*xmdoqhm4^er60=s^1g_vs7y!dl2vve4-1u9^+ps'
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = ['*']
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'hello',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'dj.urls'
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = 'dj.wsgi.application'
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/1.11/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_L10N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/1.11/howto/static-files/
|
||||
|
||||
STATIC_URL = '/static/'
|
|
@ -0,0 +1,7 @@
|
|||
from django.conf.urls import url
|
||||
|
||||
from hello import views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^hello/(?P<account_id>[0-9]+)/test$', views.hello)
|
||||
]
|
|
@ -0,0 +1,16 @@
|
|||
"""
|
||||
WSGI config for dj project.
|
||||
|
||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dj.settings')
|
||||
|
||||
application = get_wsgi_application()
|
|
@ -0,0 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
|
@ -0,0 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class HelloConfig(AppConfig):
|
||||
name = 'hello'
|
|
@ -0,0 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# from django.db import models
|
||||
|
||||
# Create your models here.
|
|
@ -0,0 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
|
@ -0,0 +1,17 @@
|
|||
import django
|
||||
from django.http import HttpResponse
|
||||
|
||||
|
||||
_body = django.x_test_body
|
||||
_headers = django.x_test_headers
|
||||
|
||||
|
||||
def hello(request, account_id):
|
||||
user_agent = request.META['HTTP_USER_AGENT'] # NOQA
|
||||
limit = request.GET.get('limit', '10') # NOQA
|
||||
response = HttpResponse(_body)
|
||||
|
||||
for name, value in _headers.items():
|
||||
response[name] = value
|
||||
|
||||
return response
|
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
|
||||
if __name__ == '__main__':
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dj.settings')
|
||||
try:
|
||||
from django.core.management import execute_from_command_line
|
||||
except ImportError:
|
||||
# The above import may fail for some other reason. Ensure that the
|
||||
# issue is really that Django is missing to avoid masking other
|
||||
# exceptions on Python 2.
|
||||
try:
|
||||
import django # NOQA
|
||||
except ImportError:
|
||||
raise ImportError(
|
||||
"Couldn't import Django. Are you sure it's installed and "
|
||||
'available on your PYTHONPATH environment variable? Did you '
|
||||
'forget to activate a virtual environment?'
|
||||
)
|
||||
raise
|
||||
execute_from_command_line(sys.argv)
|
|
@ -1,16 +1,11 @@
|
|||
import random
|
||||
|
||||
import pecan
|
||||
from pecan import expose, response, request
|
||||
|
||||
|
||||
def rand_string(min, max):
|
||||
int_gen = random.randint
|
||||
string_length = int_gen(min, max)
|
||||
return ''.join([chr(int_gen(ord('\t'), ord('~')))
|
||||
for i in range(string_length)])
|
||||
|
||||
|
||||
body = rand_string(10240, 10240)
|
||||
_body = pecan.x_test_body
|
||||
_headers = pecan.x_test_headers
|
||||
|
||||
|
||||
class TestController(object):
|
||||
|
@ -20,10 +15,10 @@ class TestController(object):
|
|||
@expose(content_type='text/plain')
|
||||
def test(self):
|
||||
user_agent = request.headers['User-Agent'] # NOQA
|
||||
limit = request.params['limit'] # NOQA
|
||||
response.headers['X-Test'] = 'Funky Chicken'
|
||||
limit = request.params.get('limit', '10') # NOQA
|
||||
response.headers.update(_headers)
|
||||
|
||||
return body
|
||||
return _body
|
||||
|
||||
|
||||
class HelloController(object):
|
||||
|
@ -36,7 +31,7 @@ class RootController(object):
|
|||
|
||||
@expose(content_type='text/plain')
|
||||
def index(self):
|
||||
response.headers['X-Test'] = 'Funky Chicken'
|
||||
return body
|
||||
response.headers.update(_headers)
|
||||
return _body
|
||||
|
||||
hello = HelloController()
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
bottle
|
||||
django
|
||||
flask
|
||||
guppy
|
||||
pecan
|
Loading…
Reference in New Issue