25 |
26 | {% include "confirmation_message.html" %}
27 | {% include "confirmation_message.html" %}
28 |
29 |
30 |
31 | {% if object3 %}
32 | {{ object3 }}
33 | {% else %}
34 | {{ object2 }}
35 | {% endif %}
36 |
37 |
38 |
39 |
40 | {% include "for_loop.html" %}
41 |
42 | {% if not object2 and objects2 %}
43 |
44 | {{ object2 }}
45 |
46 | {% endif %}
47 |
48 |
49 | {% ifnotequal num1 1 %}
50 | {% if not object3 %}
51 | {% ifnotequal 1 num2 %}
52 | {{ num2 }}
53 | {% else %}
54 |
Nothing
55 | {% endifnotequal %}
56 | {% else %}
57 | {{ num1 }}
58 | {% endif %}
59 | {% endifnotequal %}
60 |
61 |
62 | {% ifnotequal num2 0 %}
63 | {% if not object3 %}
64 | {% ifnotequal 1 num2 %}
65 | {{ num2 }}
66 | {% else %}
67 |
Nothing
68 | {% endifnotequal %}
69 | {% else %}
70 | {{ num1 }}
71 | {% endif %}
72 | {% endifnotequal %}
73 |
74 |
75 |
76 | {% ifnotequal num1 0 %}
77 | {% if not object3 %}
78 | {% ifnotequal 1 num2 %}
79 | {{ num2 }}
80 | {% else %}
81 |
Nothing
82 | {% endifnotequal %}
83 | {% else %}
84 | {{ num1 }}
85 | {% endif %}
86 | {% endifnotequal %}
87 |
88 |
89 | {% include "for_loop.html" %}
90 |
91 |
92 | {% include "sidebar.html" %}
93 |
94 |
95 |
96 | {% endblock %}
97 |
--------------------------------------------------------------------------------
/djangobench/benchmarks/default_middleware/benchmark.py:
--------------------------------------------------------------------------------
1 | from time import time
2 |
3 | from django.test.client import Client, FakePayload
4 | from django.conf import global_settings
5 | from django.conf import settings
6 | from django.core.handlers.wsgi import WSGIRequest
7 | from django.core.handlers.wsgi import WSGIHandler
8 |
9 | from djangobench.utils import run_comparison_benchmark
10 |
11 | class RequestFactory(Client):
12 | """
13 | Class that lets you create mock Request objects for use in testing.
14 |
15 | Usage:
16 |
17 | rf = RequestFactory()
18 | get_request = rf.get('/hello/')
19 | post_request = rf.post('/submit/', {'foo': 'bar'})
20 |
21 | This class re-uses the django.test.client.Client interface, docs here:
22 | http://www.djangoproject.com/documentation/testing/#the-test-client
23 |
24 | Once you have a request object you can pass it to any view function,
25 | just as if that view had been hooked up using a URLconf.
26 |
27 | Author: Simon (http://djangosnippets.org/users/simon/)
28 | djangosnippet URL: (http://djangosnippets.org/snippets/963/)
29 | """
30 | def request(self, **request):
31 | """
32 | Similar to parent class, but returns the request object as soon as it
33 | has created it.
34 | """
35 | environ = {
36 | 'HTTP_COOKIE': self.cookies,
37 | 'PATH_INFO': '/',
38 | 'QUERY_STRING': '',
39 | 'REQUEST_METHOD': 'GET',
40 | 'SCRIPT_NAME': '',
41 | 'SERVER_NAME': 'testserver',
42 | 'SERVER_PORT': 80,
43 | 'SERVER_PROTOCOL': 'HTTP/1.1',
44 | 'wsgi.input': FakePayload(''),
45 | }
46 | environ.update(self.defaults)
47 | environ.update(request)
48 |
49 | return WSGIRequest(environ)
50 |
51 | def setup():
52 | global req_factory, handler_default_middleware, handler_no_middleware
53 | req_factory = RequestFactory()
54 |
55 | settings.MIDDLEWARE_CLASSES = global_settings.MIDDLEWARE_CLASSES
56 | handler_default_middleware = WSGIHandler()
57 | handler_default_middleware.load_middleware()
58 |
59 | settings.MIDDLEWARE_CLASSES = []
60 | handler_no_middleware = WSGIHandler()
61 | handler_no_middleware.load_middleware()
62 |
63 | def benchmark_request(middleware_classes):
64 | settings.MIDDLEWARE_CLASSES = middleware_classes
65 | req_factory = RequestFactory()
66 | handler = WSGIHandler()
67 | handler.load_middleware()
68 | handler.get_response(req_factory.get('/'))
69 |
70 | def benchmark_default_middleware():
71 | global req_factory, handler_default_middleware
72 | handler_default_middleware.get_response(req_factory.get('/'))
73 |
74 | def benchmark_no_middleware():
75 | global req_factory, handler_no_middleware
76 | handler_no_middleware.get_response(req_factory.get('/'))
77 |
78 | run_comparison_benchmark(
79 | benchmark_default_middleware,
80 | benchmark_no_middleware,
81 | setup = setup,
82 | syncdb = False,
83 | meta = {
84 | 'description': 'Request/response overhead added by the default middleware.',
85 | }
86 | )
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | Djangobench
2 | ===========
3 |
4 | A harness and a set of benchmarks for measuring Django's performance over
5 | time.
6 |
7 | Running the benchmarks
8 | ----------------------
9 |
10 | Here's the short version::
11 |
12 | mkvirtualenv djangobench
13 | pip install -e git://github.com/django/djangobench.git#egg=djangobench
14 | git clone git://github.com/django/django.git
15 | cd django
16 | djangobench --control=1.2 --experiment=master
17 |
18 | Okay, so what the heck's going on here?
19 |
20 | First, ``djangobench`` doesn't test a single Django version in isolation --
21 | that wouldn't be very useful. Instead, it benchmarks an "experiment" Django
22 | against a "control", reporting on the difference between the two and
23 | measuring for statistical significance.
24 |
25 | Because a Git clone can contain all the project development history, you can
26 | test against a single repository specifying individual commit IDs, tag (as we've
27 | done above) and even possibly branches names with the ``--control`` and
28 | ``--experiment`` options.
29 |
30 | Before ``djangobench`` 0.10 you had to use ``--vcs=git`` to get this behavior.
31 | Now it's the default. There is also support for Mercurial (``--vcs=hg``).
32 |
33 | Another way to use ``djangobench``, is to run it against two complete Django
34 | source trees, you can specify this mode by using ``--vcs=none``. By default it
35 | looks for directories named ``django-control`` and ``django-experiment`` in the
36 | current working directory::
37 |
38 | djangobench --vcs=none
39 |
40 | but you can change that by using the ``--control`` or ``--experiment`` options::
41 |
42 | djangobench --vcs=none --control pristine --experiment work
43 |
44 | Now, it's impractical to install the Django source code trees under test (this
45 | is particularly true in the two-trees scenario): ``djangobench`` works its magic
46 | by mucking with ``PYTHONPATH``.
47 |
48 | However, the benchmarks themselves need access to the ``djangobench`` module, so
49 | you'll need to install it.
50 |
51 | You can specify the benchmarks to run by passing their names on the command
52 | line.
53 |
54 | This is an example of not-statistically-significant results::
55 |
56 | Running 'startup' benchmark ...
57 | Min: 0.138701 -> 0.138900: 1.0014x slower
58 | Avg: 0.139009 -> 0.139378: 1.0027x slower
59 | Not significant
60 | Stddev: 0.00044 -> 0.00046: 1.0382x larger
61 |
62 | Writing new benchmarks
63 | ----------------------
64 |
65 | Benchmarks are very simple: they're a Django app, along with a settings
66 | file, and an executable ``benchmarks.py`` that gets run by the harness. The
67 | benchmark script needs to honor a simple contract:
68 |
69 | * It's an executable Python script, run as ``__main__`` (e.g. ``python
70 | path/to/benchmark.py``). The subshell environment will have
71 | ``PYTHONPATH`` set up to point to the correct Django; it'll also have
72 | ``DJANGO_SETTINGS_MODULE`` set to ``
.settings``.
73 |
74 | * The benchmark script needs to accept a ``--trials`` argument giving
75 | the number of trials to run.
76 |
77 | * The output should be simple RFC 822-ish text -- a set of headers,
78 | followed by data points::
79 |
80 | Title: some benchmark
81 | Description: whatever the benchmark does
82 |
83 | 1.002
84 | 1.003
85 | ...
86 |
87 | The list of headers is TBD.
88 |
89 | There's a couple of utility functions in ``djangobench.utils`` that assist
90 | with honoring this contract; see those functions' docstrings for details.
91 |
92 | The existing benchmarks should be pretty easy to read for inspiration. The
93 | ``query_delete`` benchmark is probably a good place to start.
94 |
95 | **Please write new benchmarks and send us pull requests on Github!**
96 |
--------------------------------------------------------------------------------
/djangobench/utils.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import inspect
3 | import os
4 |
5 | # timeit uses either time.time() or time.clock() depending on which is more
6 | # accurate on the current platform:
7 | from timeit import default_timer as time_f
8 |
9 | try:
10 | import cProfile as profile
11 | except ImportError:
12 | import profile
13 |
14 | benchmark_parser = argparse.ArgumentParser()
15 | benchmark_parser.add_argument('-t', '--trials', type=int, default=100)
16 |
17 | def run_benchmark(benchmark, syncdb=True, setup=None, trials=None, handle_argv=True, meta={}):
18 | """
19 | Run a benchmark a few times and report the results.
20 |
21 | Arguments:
22 |
23 | benchmark
24 | The benchmark callable. ``run_benchmark`` will time
25 | the executation of this function and report those times
26 | back to the harness. However, if ``benchmark`` returns
27 | a value, that result will reported instead of the
28 | raw timing.
29 |
30 | syncdb
31 | If True, a syncdb will be performed before running
32 | the benchmark.
33 |
34 | setup
35 | A function to be called before running the benchmark
36 | function(s).
37 |
38 | trials
39 | The number of times to run the benchmark function. If not given
40 | and if ``handle_argv`` is ``True`` this'll be automatically
41 | determined from the ``--trials`` flag.
42 |
43 | handle_argv
44 | ``True`` if the script should handle ``sys.argv`` and set
45 | the number of trials accordingly.
46 |
47 | meta
48 | Key/value pairs to be returned as part of the benchmark results.
49 | """
50 | if handle_argv:
51 | args = benchmark_parser.parse_args()
52 | trials = trials or args.trials
53 |
54 | print_benchmark_header(benchmark, meta)
55 |
56 | if syncdb:
57 | from django.core.management import call_command
58 | call_command("syncdb", verbosity=0)
59 |
60 | if setup:
61 | setup()
62 |
63 | for x in xrange(trials):
64 | start = time_f()
65 | profile_file = os.environ.get('DJANGOBENCH_PROFILE_FILE', None)
66 | if profile_file is not None:
67 | loc = locals().copy()
68 | profile.runctx('benchmark_result = benchmark()', globals(), loc, profile_file)
69 | benchmark_result = loc['benchmark_result']
70 | else:
71 | benchmark_result = benchmark()
72 | if benchmark_result is not None:
73 | print benchmark_result
74 | else:
75 | print time_f() - start
76 |
77 | def run_comparison_benchmark(benchmark_a, benchmark_b, syncdb=True, setup=None, trials=None, handle_argv=True, meta={}):
78 | """
79 | Benchmark the difference between two functions.
80 |
81 | Arguments are as for ``run_benchmark``, except that this takes 2
82 | benchmark functions, an A and a B, and reports the difference between
83 | them.
84 |
85 | For example, you could use this to test the overhead of an ORM query
86 | versus a raw SQL query -- pass the ORM query as ``benchmark_a`` and the
87 | raw query as ``benchmark_b`` and this function will report the
88 | difference in time between them.
89 |
90 | For best results, the A function should be the more expensive one
91 | (otherwise djangobench will report results like "-1.2x slower", which
92 | is just confusing).
93 | """
94 | if handle_argv:
95 | args = benchmark_parser.parse_args()
96 | trials = trials or args.trials
97 |
98 | print_benchmark_header(benchmark_a, meta)
99 |
100 | if syncdb:
101 | from django.core.management import call_command
102 | call_command("syncdb", verbosity=0)
103 |
104 | if setup:
105 | setup()
106 |
107 | for x in xrange(trials):
108 | start_a = time_f()
109 | result_a = benchmark_a()
110 | result_a = result_a or time_f() - start_a
111 |
112 | start_b = time_f()
113 | result_b = benchmark_b()
114 | result_b = result_b or time_f() - start_b
115 |
116 | print result_a - result_b
117 |
118 | def print_benchmark_header(benchmark, meta):
119 | if 'title' not in map(str.lower, meta.keys()):
120 | meta['title'] = inspect.getmodule(benchmark).__name__
121 | for key, value in meta.items():
122 | print '%s: %s' % (key.lower(), value)
123 | print
--------------------------------------------------------------------------------
/djangobench/benchmarks/template_render/templates/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% spaceless %}
4 |
5 |
6 | {% block fulltitle %}{% block title %}Home{% endblock %}{% endblock %}
7 |
8 | {% block canonical %}{% endblock %}
9 |
10 | {% block meta_robots %}
11 | {% endblock %}
12 |
13 | {% block meta %}
14 |
15 |
16 | {% endblock %}
17 |
18 |
19 |
22 |
25 |
28 | {% block styles %}
29 | {% endblock %}
30 |
31 | {% block feeds %}
32 | {% endblock %}
33 |
34 |
35 |
36 |
44 | {% block scripts %}
45 | {% endblock %}
46 | {% include "somefile.js" %}
47 |
48 | {% endspaceless %}
49 |
50 |
51 |
52 | {% block alt_header %}
53 | {% if SHOW_ALT_HEADER %}
54 | {% include "header.html" %}
55 | {% endif %}
56 | {% endblock %}
57 |
58 | {% block header %}
59 |
73 | {% endblock %}
74 |
75 |
76 | {% if objects1 %}
77 | {% for obj in objects1 %}
78 | {{ object }}
79 |
80 | {% endfor %}
81 | {% endif %}
82 |
83 | {% block content %}
84 |
85 | {% block left_column %}
86 |
87 |
88 | {% endblock %}
89 |
90 | {% block right_column %}
91 |
92 |
93 | {% endblock %}
94 |
95 | {% block content_footer %}
96 |
104 | {% endblock %}
105 |
106 | {% endblock %}
107 |
108 |
109 |
110 | {% block footer %}
111 | {% include "footer.html" %}
112 | {% endblock %}
113 |
114 | {% if object3 %}
115 |
121 | {% endif %}
122 |
123 | {% block inline_js %}
124 | {% endblock %}
125 |
126 |
131 |
132 |
133 |
135 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/djangobench/main.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | """
4 | Run us some Django benchmarks.
5 | """
6 |
7 | import subprocess
8 | import argparse
9 | import email
10 | import simplejson
11 | import sys
12 | from djangobench import perf
13 | from unipath import DIRS, FSPath as Path
14 |
15 | __version__ = '0.10'
16 |
17 | DEFAULT_BENCHMARK_DIR = Path(__file__).parent.child('benchmarks').absolute()
18 |
19 | def run_benchmarks(control, experiment, benchmark_dir, benchmarks, trials, vcs=None, record_dir=None, profile_dir=None, continue_on_error=False):
20 | if benchmarks:
21 | print "Running benchmarks: %s" % " ".join(benchmarks)
22 | else:
23 | print "Running all benchmarks"
24 |
25 | if record_dir:
26 | record_dir = Path(record_dir).expand().absolute()
27 | if not record_dir.exists():
28 | raise ValueError('Recording directory "%s" does not exist' % record_dir)
29 | print "Recording data to '%s'" % record_dir
30 |
31 | control_label = get_django_version(control, vcs=vcs)
32 | experiment_label = get_django_version(experiment, vcs=vcs)
33 | branch_info = "%s branch " % vcs if vcs else ""
34 | print "Control: Django %s (in %s%s)" % (control_label, branch_info, control)
35 | print "Experiment: Django %s (in %s%s)" % (experiment_label, branch_info, experiment)
36 | print
37 |
38 | # Calculate the subshell envs that we'll use to execute the
39 | # benchmarks in.
40 | if vcs:
41 | control_env = {
42 | 'PYTHONPATH': '%s:%s' % (Path.cwd().absolute(), Path(benchmark_dir)),
43 | }
44 | experiment_env = control_env.copy()
45 | else:
46 | control_env = {'PYTHONPATH': '%s:%s' % (Path(control).absolute(), Path(benchmark_dir))}
47 | experiment_env = {'PYTHONPATH': '%s:%s' % (Path(experiment).absolute(), Path(benchmark_dir))}
48 |
49 | for benchmark in discover_benchmarks(benchmark_dir):
50 | if not benchmarks or benchmark.name in benchmarks:
51 | print "Running '%s' benchmark ..." % benchmark.name
52 | settings_mod = '%s.settings' % benchmark.name
53 | control_env['DJANGO_SETTINGS_MODULE'] = settings_mod
54 | experiment_env['DJANGO_SETTINGS_MODULE'] = settings_mod
55 | if profile_dir is not None:
56 | control_env['DJANGOBENCH_PROFILE_FILE'] = Path(profile_dir, "con-%s" % benchmark.name)
57 | experiment_env['DJANGOBENCH_PROFILE_FILE'] = Path(profile_dir, "exp-%s" % benchmark.name)
58 | try:
59 | if vcs: switch_to_branch(vcs, control)
60 | control_data = run_benchmark(benchmark, trials, control_env)
61 | if vcs: switch_to_branch(vcs, experiment)
62 | experiment_data = run_benchmark(benchmark, trials, experiment_env)
63 | except SkipBenchmark, reason:
64 | print "Skipped: %s\n" % reason
65 | continue
66 | except RuntimeError, error:
67 | if continue_on_error:
68 | print "Failed: %s\n" % error
69 | continue
70 | raise
71 |
72 | options = argparse.Namespace(
73 | track_memory = False,
74 | diff_instrumentation = False,
75 | benchmark_name = benchmark.name,
76 | disable_timelines = True,
77 | control_label = control_label,
78 | experiment_label = experiment_label,
79 | )
80 | result = perf.CompareBenchmarkData(control_data, experiment_data, options)
81 | if record_dir:
82 | record_benchmark_results(
83 | dest = record_dir.child('%s.json' % benchmark.name),
84 | name = benchmark.name,
85 | result = result,
86 | control = control_label,
87 | experiment = experiment_label,
88 | control_data = control_data,
89 | experiment_data = experiment_data,
90 | )
91 | print format_benchmark_result(result, len(control_data.runtimes))
92 | print
93 |
94 | def discover_benchmarks(benchmark_dir):
95 | for app in Path(benchmark_dir).listdir(filter=DIRS):
96 | if app.child('benchmark.py').exists() and app.child('settings.py').exists():
97 | yield app
98 |
99 | class SkipBenchmark(Exception):
100 | pass
101 |
102 | def run_benchmark(benchmark, trials, env):
103 | """
104 | Similar to perf.MeasureGeneric, but modified a bit for our purposes.
105 | """
106 | # Remove Pycs, then call the command once to prime the pump and
107 | # re-generate fresh ones. This makes sure we're measuring as little of
108 | # Python's startup time as possible.
109 | RemovePycs()
110 | command = [sys.executable, '%s/benchmark.py' % benchmark]
111 | out, _, _ = perf.CallAndCaptureOutput(command + ['-t', 1], env, track_memory=False, inherit_env=[])
112 | if out.startswith('SKIP:'):
113 | raise SkipBenchmark(out.replace('SKIP:', '').strip())
114 |
115 | # Now do the actual mesurements.
116 | output = perf.CallAndCaptureOutput(command + ['-t', str(trials)], env, track_memory=False, inherit_env=[])
117 | stdout, stderr, mem_usage = output
118 | message = email.message_from_string(stdout)
119 | data_points = [float(line) for line in message.get_payload().splitlines()]
120 | return perf.RawData(data_points, mem_usage, inst_output=stderr)
121 |
122 | def record_benchmark_results(dest, **kwargs):
123 | kwargs['version'] = __version__
124 | simplejson.dump(kwargs, open(dest, 'w'), default=json_encode_custom)
125 |
126 | def json_encode_custom(obj):
127 | if isinstance(obj, perf.RawData):
128 | return obj.runtimes
129 | if isinstance(obj, perf.BenchmarkResult):
130 | return {
131 | 'min_base' : obj.min_base,
132 | 'min_changed' : obj.min_changed,
133 | 'delta_min' : obj.delta_min,
134 | 'avg_base' : obj.avg_base,
135 | 'avg_changed' : obj.avg_changed,
136 | 'delta_avg' : obj.delta_avg,
137 | 't_msg' : obj.t_msg,
138 | 'std_base' : obj.std_base,
139 | 'std_changed' : obj.std_changed,
140 | 'delta_std' : obj.delta_std,
141 | }
142 | if isinstance(obj, perf.SimpleBenchmarkResult):
143 | return {
144 | 'base_time' : obj.base_time,
145 | 'changed_time' : obj.changed_time,
146 | 'time_delta' : obj.time_delta,
147 | }
148 | raise TypeError("%r is not JSON serializable" % obj)
149 |
150 | def supports_color():
151 | return sys.platform != 'win32' and hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()
152 |
153 | class colorize(object):
154 | GOOD = INSIGNIFICANT = SIGNIFICANT = BAD = ENDC = ''
155 | if supports_color():
156 | GOOD = '\033[92m'
157 | INSIGNIFICANT = '\033[94m'
158 | SIGNIFICANT = '\033[93m'
159 | BAD = '\033[91m'
160 | ENDC = '\033[0m'
161 |
162 | @classmethod
163 | def colorize(cls, color, text):
164 | return "%s%s%s" % (color, text, cls.ENDC)
165 |
166 | @classmethod
167 | def good(cls, text):
168 | return cls.colorize(cls.GOOD, text)
169 |
170 | @classmethod
171 | def significant(cls, text):
172 | return cls.colorize(cls.SIGNIFICANT, text)
173 |
174 | @classmethod
175 | def insignificant(cls, text):
176 | return cls.colorize(cls.INSIGNIFICANT, text)
177 |
178 | @classmethod
179 | def bad(cls, text):
180 | return cls.colorize(cls.BAD, text)
181 |
182 | def format_benchmark_result(result, num_points):
183 | if isinstance(result, perf.BenchmarkResult):
184 | output = ''
185 | delta_min = result.delta_min
186 | if 'faster' in delta_min:
187 | delta_min = colorize.good(delta_min)
188 | elif 'slower' in result.delta_min:
189 | delta_min = colorize.bad(delta_min)
190 | output += "Min: %f -> %f: %s\n" % (result.min_base, result.min_changed, delta_min)
191 |
192 | delta_avg = result.delta_avg
193 | if 'faster' in delta_avg:
194 | delta_avg = colorize.good(delta_avg)
195 | elif 'slower' in delta_avg:
196 | delta_avg = colorize.bad(delta_avg)
197 | output += "Avg: %f -> %f: %s\n" % (result.avg_base, result.avg_changed, delta_avg)
198 |
199 | t_msg = result.t_msg
200 | if 'Not significant' in t_msg:
201 | t_msg = colorize.insignificant(t_msg)
202 | elif 'Significant' in result.t_msg:
203 | t_msg = colorize.significant(t_msg)
204 | output += t_msg
205 |
206 | delta_std = result.delta_std
207 | if 'larger' in delta_std:
208 | delta_std = colorize.bad(delta_std)
209 | elif 'smaller' in delta_std:
210 | delta_std = colorize.good(delta_std)
211 | output += "Stddev: %.5f -> %.5f: %s" %(result.std_base, result.std_changed, delta_std)
212 | output += " (N = %s)" % num_points
213 | output += result.get_timeline()
214 | return output
215 | else:
216 | return str(result)
217 |
218 | def get_django_version(loc, vcs=None):
219 | if vcs:
220 | switch_to_branch(vcs, loc, do_cleanup=True)
221 | pythonpath = Path.cwd()
222 | else:
223 | pythonpath = Path(loc).absolute()
224 | out, err, _ = perf.CallAndCaptureOutput(
225 | [sys.executable, '-c' 'import django; print django.get_version()'],
226 | env = {'PYTHONPATH': pythonpath}
227 | )
228 | return out.strip()
229 |
230 | def switch_to_branch(vcs, branchname, do_cleanup=False):
231 | if vcs == 'git':
232 | cmd = ['git', 'checkout', branchname]
233 | elif vcs == 'hg':
234 | cmd = ['hg', 'update', '-C', branchname]
235 | else:
236 | raise ValueError("Sorry, %s isn't supported (yet?)" % vcs)
237 | if do_cleanup:
238 | RemovePycs(vcs=vcs)
239 | subprocess.check_call(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
240 |
241 | def RemovePycs(vcs=None):
242 | if vcs == 'git':
243 | cmd = ['git', 'clean', '-fdX']
244 | subprocess.check_call(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
245 | else:
246 | perf.RemovePycs()
247 |
248 | def main():
249 | parser = argparse.ArgumentParser()
250 | parser.add_argument(
251 | '--control',
252 | metavar = 'PATH',
253 | default = 'django-control',
254 | help = "Path to the Django code tree to use as control."
255 | )
256 | parser.add_argument(
257 | '--experiment',
258 | metavar = 'PATH',
259 | default = 'django-experiment',
260 | help = "Path to the Django version to use as experiment."
261 | )
262 | parser.add_argument(
263 | '--vcs',
264 | choices = ['git', 'hg', 'none'],
265 | default = 'git',
266 | help = 'Use a VCS for control/experiment. Makes --control/--experiment specify branches, not paths.'
267 | )
268 | parser.add_argument(
269 | '-t', '--trials',
270 | type = int,
271 | default = 50,
272 | help = 'Number of times to run each benchmark.'
273 | )
274 | parser.add_argument(
275 | '-r', '--record',
276 | default = None,
277 | metavar = 'PATH',
278 | help = 'Directory to record detailed output as a series of JSON files.',
279 | )
280 |
281 | parser.add_argument(
282 | '--benchmark-dir',
283 | dest = 'benchmark_dir',
284 | metavar = 'PATH',
285 | default = DEFAULT_BENCHMARK_DIR,
286 | help = ('Directory to inspect for benchmarks. Defaults to the '
287 | 'benchmarks included with djangobench.'),
288 | )
289 | parser.add_argument(
290 | 'benchmarks',
291 | metavar = 'name',
292 | default = None,
293 | help = "Benchmarks to be run. Defaults to all.",
294 | nargs = '*'
295 | )
296 | parser.add_argument(
297 | '-p',
298 | '--profile-dir',
299 | dest = 'profile_dir',
300 | default = None,
301 | metavar = 'PATH',
302 | help = 'Directory to record profiling statistics for the control and experimental run of each benchmark'
303 | )
304 | parser.add_argument(
305 | '--continue-on-error',
306 | dest = 'continue_on_error',
307 | action = 'store_true',
308 | help = 'Continue with the remaining benchmarks if any fail',
309 | )
310 |
311 | args = parser.parse_args()
312 | run_benchmarks(
313 | control = args.control,
314 | experiment = args.experiment,
315 | benchmark_dir = args.benchmark_dir,
316 | benchmarks = args.benchmarks,
317 | trials = args.trials,
318 | vcs = None if args.vcs == 'none' else args.vcs,
319 | record_dir = args.record,
320 | profile_dir = args.profile_dir,
321 | continue_on_error = args.continue_on_error
322 | )
323 |
324 | if __name__ == '__main__':
325 | main()
326 |
--------------------------------------------------------------------------------
/djangobench/benchmarks/query_select_related/fixtures/initial_data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "model": "query_select_related.author",
4 | "pk": 1,
5 | "fields": {
6 | "author": 1
7 | }
8 | },
9 | {
10 | "model": "query_select_related.author",
11 | "pk": 2,
12 | "fields": {
13 | "author": 2
14 | }
15 | },
16 | {
17 | "model": "query_select_related.author",
18 | "pk": 3,
19 | "fields": {
20 | "author": 3
21 | }
22 | },
23 | {
24 | "model": "query_select_related.author",
25 | "pk": 4,
26 | "fields": {
27 | "author": 4
28 | }
29 | },
30 | {
31 | "model": "query_select_related.author",
32 | "pk": 5,
33 | "fields": {
34 | "author": 5
35 | }
36 | },
37 | {
38 | "model": "query_select_related.author",
39 | "pk": 6,
40 | "fields": {
41 | "author": 6
42 | }
43 | },
44 | {
45 | "model": "query_select_related.author",
46 | "pk": 7,
47 | "fields": {
48 | "author": 7
49 | }
50 | },
51 | {
52 | "model": "query_select_related.author",
53 | "pk": 8,
54 | "fields": {
55 | "author": 8
56 | }
57 | },
58 | {
59 | "model": "query_select_related.author",
60 | "pk": 9,
61 | "fields": {
62 | "author": 9
63 | }
64 | },
65 | {
66 | "model": "query_select_related.author",
67 | "pk": 10,
68 | "fields": {
69 | "author": 10
70 | }
71 | },
72 | {
73 | "model": "query_select_related.author",
74 | "pk": 11,
75 | "fields": {
76 | "author": 11
77 | }
78 | },
79 | {
80 | "model": "query_select_related.author",
81 | "pk": 12,
82 | "fields": {
83 | "author": 12
84 | }
85 | },
86 | {
87 | "model": "query_select_related.author",
88 | "pk": 13,
89 | "fields": {
90 | "author": 13
91 | }
92 | },
93 | {
94 | "model": "query_select_related.author",
95 | "pk": 14,
96 | "fields": {
97 | "author": 14
98 | }
99 | },
100 | {
101 | "model": "query_select_related.author",
102 | "pk": 15,
103 | "fields": {
104 | "author": 15
105 | }
106 | },
107 | {
108 | "model": "query_select_related.author",
109 | "pk": 16,
110 | "fields": {
111 | "author": 16
112 | }
113 | },
114 | {
115 | "model": "query_select_related.author",
116 | "pk": 17,
117 | "fields": {
118 | "author": 17
119 | }
120 | },
121 | {
122 | "model": "query_select_related.author",
123 | "pk": 18,
124 | "fields": {
125 | "author": 18
126 | }
127 | },
128 | {
129 | "model": "query_select_related.author",
130 | "pk": 19,
131 | "fields": {
132 | "author": 19
133 | }
134 | },
135 | {
136 | "model": "query_select_related.author",
137 | "pk": 20,
138 | "fields": {
139 | "author": 20
140 | }
141 | },
142 | {
143 | "model": "query_select_related.author",
144 | "pk": 21,
145 | "fields": {
146 | "author": 21
147 | }
148 | },
149 | {
150 | "model": "query_select_related.author",
151 | "pk": 22,
152 | "fields": {
153 | "author": 22
154 | }
155 | },
156 | {
157 | "model": "query_select_related.author",
158 | "pk": 23,
159 | "fields": {
160 | "author": 23
161 | }
162 | },
163 | {
164 | "model": "query_select_related.author",
165 | "pk": 24,
166 | "fields": {
167 | "author": 24
168 | }
169 | },
170 | {
171 | "model": "query_select_related.author",
172 | "pk": 25,
173 | "fields": {
174 | "author": 25
175 | }
176 | },
177 | {
178 | "model": "query_select_related.author",
179 | "pk": 26,
180 | "fields": {
181 | "author": 26
182 | }
183 | },
184 | {
185 | "model": "query_select_related.author",
186 | "pk": 27,
187 | "fields": {
188 | "author": 27
189 | }
190 | },
191 | {
192 | "model": "query_select_related.author",
193 | "pk": 28,
194 | "fields": {
195 | "author": 28
196 | }
197 | },
198 | {
199 | "model": "query_select_related.author",
200 | "pk": 29,
201 | "fields": {
202 | "author": 29
203 | }
204 | },
205 | {
206 | "model": "query_select_related.author",
207 | "pk": 30,
208 | "fields": {
209 | "author": 30
210 | }
211 | },
212 | {
213 | "model": "query_select_related.author",
214 | "pk": 31,
215 | "fields": {
216 | "author": 31
217 | }
218 | },
219 | {
220 | "model": "query_select_related.author",
221 | "pk": 32,
222 | "fields": {
223 | "author": 32
224 | }
225 | },
226 | {
227 | "model": "query_select_related.author",
228 | "pk": 33,
229 | "fields": {
230 | "author": 33
231 | }
232 | },
233 | {
234 | "model": "query_select_related.author",
235 | "pk": 34,
236 | "fields": {
237 | "author": 34
238 | }
239 | },
240 | {
241 | "model": "query_select_related.author",
242 | "pk": 35,
243 | "fields": {
244 | "author": 35
245 | }
246 | },
247 | {
248 | "model": "query_select_related.author",
249 | "pk": 36,
250 | "fields": {
251 | "author": 36
252 | }
253 | },
254 | {
255 | "model": "query_select_related.author",
256 | "pk": 37,
257 | "fields": {
258 | "author": 37
259 | }
260 | },
261 | {
262 | "model": "query_select_related.author",
263 | "pk": 38,
264 | "fields": {
265 | "author": 38
266 | }
267 | },
268 | {
269 | "model": "query_select_related.author",
270 | "pk": 39,
271 | "fields": {
272 | "author": 39
273 | }
274 | },
275 | {
276 | "model": "query_select_related.author",
277 | "pk": 40,
278 | "fields": {
279 | "author": 40
280 | }
281 | },
282 | {
283 | "model": "query_select_related.author",
284 | "pk": 41,
285 | "fields": {
286 | "author": 41
287 | }
288 | },
289 | {
290 | "model": "query_select_related.author",
291 | "pk": 42,
292 | "fields": {
293 | "author": 42
294 | }
295 | },
296 | {
297 | "model": "query_select_related.author",
298 | "pk": 43,
299 | "fields": {
300 | "author": 43
301 | }
302 | },
303 | {
304 | "model": "query_select_related.author",
305 | "pk": 44,
306 | "fields": {
307 | "author": 44
308 | }
309 | },
310 | {
311 | "model": "query_select_related.author",
312 | "pk": 45,
313 | "fields": {
314 | "author": 45
315 | }
316 | },
317 | {
318 | "model": "query_select_related.author",
319 | "pk": 46,
320 | "fields": {
321 | "author": 46
322 | }
323 | },
324 | {
325 | "model": "query_select_related.author",
326 | "pk": 47,
327 | "fields": {
328 | "author": 47
329 | }
330 | },
331 | {
332 | "model": "query_select_related.author",
333 | "pk": 48,
334 | "fields": {
335 | "author": 48
336 | }
337 | },
338 | {
339 | "model": "query_select_related.author",
340 | "pk": 49,
341 | "fields": {
342 | "author": 49
343 | }
344 | },
345 | {
346 | "model": "query_select_related.author",
347 | "pk": 50,
348 | "fields": {
349 | "author": 50
350 | }
351 | },
352 | {
353 | "model": "query_select_related.author",
354 | "pk": 51,
355 | "fields": {
356 | "author": 51
357 | }
358 | },
359 | {
360 | "model": "query_select_related.author",
361 | "pk": 52,
362 | "fields": {
363 | "author": 52
364 | }
365 | },
366 | {
367 | "model": "query_select_related.author",
368 | "pk": 53,
369 | "fields": {
370 | "author": 53
371 | }
372 | },
373 | {
374 | "model": "query_select_related.author",
375 | "pk": 54,
376 | "fields": {
377 | "author": 54
378 | }
379 | },
380 | {
381 | "model": "query_select_related.author",
382 | "pk": 55,
383 | "fields": {
384 | "author": 55
385 | }
386 | },
387 | {
388 | "model": "query_select_related.author",
389 | "pk": 56,
390 | "fields": {
391 | "author": 56
392 | }
393 | },
394 | {
395 | "model": "query_select_related.author",
396 | "pk": 57,
397 | "fields": {
398 | "author": 57
399 | }
400 | },
401 | {
402 | "model": "query_select_related.author",
403 | "pk": 58,
404 | "fields": {
405 | "author": 58
406 | }
407 | },
408 | {
409 | "model": "query_select_related.author",
410 | "pk": 59,
411 | "fields": {
412 | "author": 59
413 | }
414 | },
415 | {
416 | "model": "query_select_related.author",
417 | "pk": 60,
418 | "fields": {
419 | "author": 60
420 | }
421 | },
422 | {
423 | "model": "query_select_related.author",
424 | "pk": 61,
425 | "fields": {
426 | "author": 61
427 | }
428 | },
429 | {
430 | "model": "query_select_related.author",
431 | "pk": 62,
432 | "fields": {
433 | "author": 62
434 | }
435 | },
436 | {
437 | "model": "query_select_related.author",
438 | "pk": 63,
439 | "fields": {
440 | "author": 63
441 | }
442 | },
443 | {
444 | "model": "query_select_related.author",
445 | "pk": 64,
446 | "fields": {
447 | "author": 64
448 | }
449 | },
450 | {
451 | "model": "query_select_related.author",
452 | "pk": 65,
453 | "fields": {
454 | "author": 65
455 | }
456 | },
457 | {
458 | "model": "query_select_related.author",
459 | "pk": 66,
460 | "fields": {
461 | "author": 66
462 | }
463 | },
464 | {
465 | "model": "query_select_related.author",
466 | "pk": 67,
467 | "fields": {
468 | "author": 67
469 | }
470 | },
471 | {
472 | "model": "query_select_related.author",
473 | "pk": 68,
474 | "fields": {
475 | "author": 68
476 | }
477 | },
478 | {
479 | "model": "query_select_related.author",
480 | "pk": 69,
481 | "fields": {
482 | "author": 69
483 | }
484 | },
485 | {
486 | "model": "query_select_related.author",
487 | "pk": 70,
488 | "fields": {
489 | "author": 70
490 | }
491 | },
492 | {
493 | "model": "query_select_related.author",
494 | "pk": 71,
495 | "fields": {
496 | "author": 71
497 | }
498 | },
499 | {
500 | "model": "query_select_related.author",
501 | "pk": 72,
502 | "fields": {
503 | "author": 72
504 | }
505 | },
506 | {
507 | "model": "query_select_related.author",
508 | "pk": 73,
509 | "fields": {
510 | "author": 73
511 | }
512 | },
513 | {
514 | "model": "query_select_related.author",
515 | "pk": 74,
516 | "fields": {
517 | "author": 74
518 | }
519 | },
520 | {
521 | "model": "query_select_related.author",
522 | "pk": 75,
523 | "fields": {
524 | "author": 75
525 | }
526 | },
527 | {
528 | "model": "query_select_related.author",
529 | "pk": 76,
530 | "fields": {
531 | "author": 76
532 | }
533 | },
534 | {
535 | "model": "query_select_related.author",
536 | "pk": 77,
537 | "fields": {
538 | "author": 77
539 | }
540 | },
541 | {
542 | "model": "query_select_related.author",
543 | "pk": 78,
544 | "fields": {
545 | "author": 78
546 | }
547 | },
548 | {
549 | "model": "query_select_related.author",
550 | "pk": 79,
551 | "fields": {
552 | "author": 79
553 | }
554 | },
555 | {
556 | "model": "query_select_related.author",
557 | "pk": 80,
558 | "fields": {
559 | "author": 80
560 | }
561 | },
562 | {
563 | "model": "query_select_related.author",
564 | "pk": 81,
565 | "fields": {
566 | "author": 81
567 | }
568 | },
569 | {
570 | "model": "query_select_related.author",
571 | "pk": 82,
572 | "fields": {
573 | "author": 82
574 | }
575 | },
576 | {
577 | "model": "query_select_related.author",
578 | "pk": 83,
579 | "fields": {
580 | "author": 83
581 | }
582 | },
583 | {
584 | "model": "query_select_related.author",
585 | "pk": 84,
586 | "fields": {
587 | "author": 84
588 | }
589 | },
590 | {
591 | "model": "query_select_related.author",
592 | "pk": 85,
593 | "fields": {
594 | "author": 85
595 | }
596 | },
597 | {
598 | "model": "query_select_related.author",
599 | "pk": 86,
600 | "fields": {
601 | "author": 86
602 | }
603 | },
604 | {
605 | "model": "query_select_related.author",
606 | "pk": 87,
607 | "fields": {
608 | "author": 87
609 | }
610 | },
611 | {
612 | "model": "query_select_related.author",
613 | "pk": 88,
614 | "fields": {
615 | "author": 88
616 | }
617 | },
618 | {
619 | "model": "query_select_related.author",
620 | "pk": 89,
621 | "fields": {
622 | "author": 89
623 | }
624 | },
625 | {
626 | "model": "query_select_related.author",
627 | "pk": 90,
628 | "fields": {
629 | "author": 90
630 | }
631 | },
632 | {
633 | "model": "query_select_related.author",
634 | "pk": 91,
635 | "fields": {
636 | "author": 91
637 | }
638 | },
639 | {
640 | "model": "query_select_related.author",
641 | "pk": 92,
642 | "fields": {
643 | "author": 92
644 | }
645 | },
646 | {
647 | "model": "query_select_related.author",
648 | "pk": 93,
649 | "fields": {
650 | "author": 93
651 | }
652 | },
653 | {
654 | "model": "query_select_related.author",
655 | "pk": 94,
656 | "fields": {
657 | "author": 94
658 | }
659 | },
660 | {
661 | "model": "query_select_related.author",
662 | "pk": 95,
663 | "fields": {
664 | "author": 95
665 | }
666 | },
667 | {
668 | "model": "query_select_related.author",
669 | "pk": 96,
670 | "fields": {
671 | "author": 96
672 | }
673 | },
674 | {
675 | "model": "query_select_related.author",
676 | "pk": 97,
677 | "fields": {
678 | "author": 97
679 | }
680 | },
681 | {
682 | "model": "query_select_related.author",
683 | "pk": 98,
684 | "fields": {
685 | "author": 98
686 | }
687 | },
688 | {
689 | "model": "query_select_related.author",
690 | "pk": 99,
691 | "fields": {
692 | "author": 99
693 | }
694 | },
695 | {
696 | "model": "query_select_related.author",
697 | "pk": 100,
698 | "fields": {
699 | "author": 100
700 | }
701 | },
702 | {
703 | "model": "query_select_related.book",
704 | "pk": 1,
705 | "fields": {
706 | "title": "a",
707 | "author": 1
708 | }
709 | },
710 | {
711 | "model": "query_select_related.book",
712 | "pk": 2,
713 | "fields": {
714 | "title": "b",
715 | "author": 2
716 | }
717 | },
718 | {
719 | "model": "query_select_related.book",
720 | "pk": 3,
721 | "fields": {
722 | "title": "b",
723 | "author": 3
724 | }
725 | },
726 | {
727 | "model": "query_select_related.book",
728 | "pk": 4,
729 | "fields": {
730 | "title": "b",
731 | "author": 4
732 | }
733 | },
734 | {
735 | "model": "query_select_related.book",
736 | "pk": 5,
737 | "fields": {
738 | "title": "b",
739 | "author": 5
740 | }
741 | },
742 | {
743 | "model": "query_select_related.book",
744 | "pk": 6,
745 | "fields": {
746 | "title": "a",
747 | "author": 6
748 | }
749 | },
750 | {
751 | "model": "query_select_related.book",
752 | "pk": 7,
753 | "fields": {
754 | "title": "a",
755 | "author": 7
756 | }
757 | },
758 | {
759 | "model": "query_select_related.book",
760 | "pk": 8,
761 | "fields": {
762 | "title": "a",
763 | "author": 8
764 | }
765 | },
766 | {
767 | "model": "query_select_related.book",
768 | "pk": 9,
769 | "fields": {
770 | "title": "a",
771 | "author": 9
772 | }
773 | },
774 | {
775 | "model": "query_select_related.book",
776 | "pk": 10,
777 | "fields": {
778 | "title": "a",
779 | "author": 10
780 | }
781 | },
782 | {
783 | "model": "query_select_related.book",
784 | "pk": 11,
785 | "fields": {
786 | "title": "a",
787 | "author": 11
788 | }
789 | },
790 | {
791 | "model": "query_select_related.book",
792 | "pk": 12,
793 | "fields": {
794 | "title": "a",
795 | "author": 12
796 | }
797 | },
798 | {
799 | "model": "query_select_related.book",
800 | "pk": 13,
801 | "fields": {
802 | "title": "a",
803 | "author": 13
804 | }
805 | },
806 | {
807 | "model": "query_select_related.book",
808 | "pk": 14,
809 | "fields": {
810 | "title": "a",
811 | "author": 14
812 | }
813 | },
814 | {
815 | "model": "query_select_related.book",
816 | "pk": 15,
817 | "fields": {
818 | "title": "a",
819 | "author": 15
820 | }
821 | },
822 | {
823 | "model": "query_select_related.book",
824 | "pk": 16,
825 | "fields": {
826 | "title": "a",
827 | "author": 16
828 | }
829 | },
830 | {
831 | "model": "query_select_related.book",
832 | "pk": 17,
833 | "fields": {
834 | "title": "a",
835 | "author": 17
836 | }
837 | },
838 | {
839 | "model": "query_select_related.book",
840 | "pk": 18,
841 | "fields": {
842 | "title": "a",
843 | "author": 18
844 | }
845 | },
846 | {
847 | "model": "query_select_related.book",
848 | "pk": 19,
849 | "fields": {
850 | "title": "a",
851 | "author": 19
852 | }
853 | },
854 | {
855 | "model": "query_select_related.book",
856 | "pk": 20,
857 | "fields": {
858 | "title": "a",
859 | "author": 20
860 | }
861 | },
862 | {
863 | "model": "query_select_related.book",
864 | "pk": 21,
865 | "fields": {
866 | "title": "a",
867 | "author": 21
868 | }
869 | },
870 | {
871 | "model": "query_select_related.book",
872 | "pk": 22,
873 | "fields": {
874 | "title": "a",
875 | "author": 22
876 | }
877 | },
878 | {
879 | "model": "query_select_related.book",
880 | "pk": 23,
881 | "fields": {
882 | "title": "a",
883 | "author": 23
884 | }
885 | },
886 | {
887 | "model": "query_select_related.book",
888 | "pk": 24,
889 | "fields": {
890 | "title": "a",
891 | "author": 24
892 | }
893 | },
894 | {
895 | "model": "query_select_related.book",
896 | "pk": 25,
897 | "fields": {
898 | "title": "a",
899 | "author": 25
900 | }
901 | },
902 | {
903 | "model": "query_select_related.book",
904 | "pk": 26,
905 | "fields": {
906 | "title": "a",
907 | "author": 26
908 | }
909 | },
910 | {
911 | "model": "query_select_related.book",
912 | "pk": 27,
913 | "fields": {
914 | "title": "a",
915 | "author": 27
916 | }
917 | },
918 | {
919 | "model": "query_select_related.book",
920 | "pk": 28,
921 | "fields": {
922 | "title": "a",
923 | "author": 28
924 | }
925 | },
926 | {
927 | "model": "query_select_related.book",
928 | "pk": 29,
929 | "fields": {
930 | "title": "a",
931 | "author": 29
932 | }
933 | },
934 | {
935 | "model": "query_select_related.book",
936 | "pk": 30,
937 | "fields": {
938 | "title": "a",
939 | "author": 30
940 | }
941 | },
942 | {
943 | "model": "query_select_related.book",
944 | "pk": 31,
945 | "fields": {
946 | "title": "a",
947 | "author": 31
948 | }
949 | },
950 | {
951 | "model": "query_select_related.book",
952 | "pk": 32,
953 | "fields": {
954 | "title": "a",
955 | "author": 32
956 | }
957 | },
958 | {
959 | "model": "query_select_related.book",
960 | "pk": 33,
961 | "fields": {
962 | "title": "a",
963 | "author": 33
964 | }
965 | },
966 | {
967 | "model": "query_select_related.book",
968 | "pk": 34,
969 | "fields": {
970 | "title": "a",
971 | "author": 34
972 | }
973 | },
974 | {
975 | "model": "query_select_related.book",
976 | "pk": 35,
977 | "fields": {
978 | "title": "a",
979 | "author": 35
980 | }
981 | },
982 | {
983 | "model": "query_select_related.book",
984 | "pk": 36,
985 | "fields": {
986 | "title": "a",
987 | "author": 36
988 | }
989 | },
990 | {
991 | "model": "query_select_related.book",
992 | "pk": 37,
993 | "fields": {
994 | "title": "a",
995 | "author": 37
996 | }
997 | },
998 | {
999 | "model": "query_select_related.book",
1000 | "pk": 38,
1001 | "fields": {
1002 | "title": "a",
1003 | "author": 38
1004 | }
1005 | },
1006 | {
1007 | "model": "query_select_related.book",
1008 | "pk": 39,
1009 | "fields": {
1010 | "title": "a",
1011 | "author": 39
1012 | }
1013 | },
1014 | {
1015 | "model": "query_select_related.book",
1016 | "pk": 40,
1017 | "fields": {
1018 | "title": "a",
1019 | "author": 40
1020 | }
1021 | },
1022 | {
1023 | "model": "query_select_related.book",
1024 | "pk": 41,
1025 | "fields": {
1026 | "title": "a",
1027 | "author": 41
1028 | }
1029 | },
1030 | {
1031 | "model": "query_select_related.book",
1032 | "pk": 42,
1033 | "fields": {
1034 | "title": "a",
1035 | "author": 42
1036 | }
1037 | },
1038 | {
1039 | "model": "query_select_related.book",
1040 | "pk": 43,
1041 | "fields": {
1042 | "title": "a",
1043 | "author": 43
1044 | }
1045 | },
1046 | {
1047 | "model": "query_select_related.book",
1048 | "pk": 44,
1049 | "fields": {
1050 | "title": "a",
1051 | "author": 44
1052 | }
1053 | },
1054 | {
1055 | "model": "query_select_related.book",
1056 | "pk": 45,
1057 | "fields": {
1058 | "title": "a",
1059 | "author": 45
1060 | }
1061 | },
1062 | {
1063 | "model": "query_select_related.book",
1064 | "pk": 46,
1065 | "fields": {
1066 | "title": "a",
1067 | "author": 46
1068 | }
1069 | },
1070 | {
1071 | "model": "query_select_related.book",
1072 | "pk": 47,
1073 | "fields": {
1074 | "title": "a",
1075 | "author": 47
1076 | }
1077 | },
1078 | {
1079 | "model": "query_select_related.book",
1080 | "pk": 48,
1081 | "fields": {
1082 | "title": "a",
1083 | "author": 48
1084 | }
1085 | },
1086 | {
1087 | "model": "query_select_related.book",
1088 | "pk": 49,
1089 | "fields": {
1090 | "title": "a",
1091 | "author": 49
1092 | }
1093 | },
1094 | {
1095 | "model": "query_select_related.book",
1096 | "pk": 50,
1097 | "fields": {
1098 | "title": "a",
1099 | "author": 50
1100 | }
1101 | },
1102 | {
1103 | "model": "query_select_related.book",
1104 | "pk": 51,
1105 | "fields": {
1106 | "title": "a",
1107 | "author": 51
1108 | }
1109 | },
1110 | {
1111 | "model": "query_select_related.book",
1112 | "pk": 52,
1113 | "fields": {
1114 | "title": "a",
1115 | "author": 52
1116 | }
1117 | },
1118 | {
1119 | "model": "query_select_related.book",
1120 | "pk": 53,
1121 | "fields": {
1122 | "title": "a",
1123 | "author": 53
1124 | }
1125 | },
1126 | {
1127 | "model": "query_select_related.book",
1128 | "pk": 54,
1129 | "fields": {
1130 | "title": "a",
1131 | "author": 54
1132 | }
1133 | },
1134 | {
1135 | "model": "query_select_related.book",
1136 | "pk": 55,
1137 | "fields": {
1138 | "title": "a",
1139 | "author": 55
1140 | }
1141 | },
1142 | {
1143 | "model": "query_select_related.book",
1144 | "pk": 56,
1145 | "fields": {
1146 | "title": "a",
1147 | "author": 56
1148 | }
1149 | },
1150 | {
1151 | "model": "query_select_related.book",
1152 | "pk": 57,
1153 | "fields": {
1154 | "title": "a",
1155 | "author": 57
1156 | }
1157 | },
1158 | {
1159 | "model": "query_select_related.book",
1160 | "pk": 58,
1161 | "fields": {
1162 | "title": "a",
1163 | "author": 58
1164 | }
1165 | },
1166 | {
1167 | "model": "query_select_related.book",
1168 | "pk": 59,
1169 | "fields": {
1170 | "title": "a",
1171 | "author": 59
1172 | }
1173 | },
1174 | {
1175 | "model": "query_select_related.book",
1176 | "pk": 60,
1177 | "fields": {
1178 | "title": "a",
1179 | "author": 60
1180 | }
1181 | },
1182 | {
1183 | "model": "query_select_related.book",
1184 | "pk": 61,
1185 | "fields": {
1186 | "title": "a",
1187 | "author": 61
1188 | }
1189 | },
1190 | {
1191 | "model": "query_select_related.book",
1192 | "pk": 62,
1193 | "fields": {
1194 | "title": "a",
1195 | "author": 62
1196 | }
1197 | },
1198 | {
1199 | "model": "query_select_related.book",
1200 | "pk": 63,
1201 | "fields": {
1202 | "title": "a",
1203 | "author": 63
1204 | }
1205 | },
1206 | {
1207 | "model": "query_select_related.book",
1208 | "pk": 64,
1209 | "fields": {
1210 | "title": "a",
1211 | "author": 64
1212 | }
1213 | },
1214 | {
1215 | "model": "query_select_related.book",
1216 | "pk": 65,
1217 | "fields": {
1218 | "title": "a",
1219 | "author": 65
1220 | }
1221 | },
1222 | {
1223 | "model": "query_select_related.book",
1224 | "pk": 66,
1225 | "fields": {
1226 | "title": "a",
1227 | "author": 66
1228 | }
1229 | },
1230 | {
1231 | "model": "query_select_related.book",
1232 | "pk": 67,
1233 | "fields": {
1234 | "title": "a",
1235 | "author": 67
1236 | }
1237 | },
1238 | {
1239 | "model": "query_select_related.book",
1240 | "pk": 68,
1241 | "fields": {
1242 | "title": "a",
1243 | "author": 68
1244 | }
1245 | },
1246 | {
1247 | "model": "query_select_related.book",
1248 | "pk": 69,
1249 | "fields": {
1250 | "title": "a",
1251 | "author": 69
1252 | }
1253 | },
1254 | {
1255 | "model": "query_select_related.book",
1256 | "pk": 70,
1257 | "fields": {
1258 | "title": "a",
1259 | "author": 70
1260 | }
1261 | },
1262 | {
1263 | "model": "query_select_related.book",
1264 | "pk": 71,
1265 | "fields": {
1266 | "title": "a",
1267 | "author": 71
1268 | }
1269 | },
1270 | {
1271 | "model": "query_select_related.book",
1272 | "pk": 72,
1273 | "fields": {
1274 | "title": "a",
1275 | "author": 72
1276 | }
1277 | },
1278 | {
1279 | "model": "query_select_related.book",
1280 | "pk": 73,
1281 | "fields": {
1282 | "title": "a",
1283 | "author": 73
1284 | }
1285 | },
1286 | {
1287 | "model": "query_select_related.book",
1288 | "pk": 74,
1289 | "fields": {
1290 | "title": "a",
1291 | "author": 74
1292 | }
1293 | },
1294 | {
1295 | "model": "query_select_related.book",
1296 | "pk": 75,
1297 | "fields": {
1298 | "title": "a",
1299 | "author": 75
1300 | }
1301 | },
1302 | {
1303 | "model": "query_select_related.book",
1304 | "pk": 76,
1305 | "fields": {
1306 | "title": "a",
1307 | "author": 76
1308 | }
1309 | },
1310 | {
1311 | "model": "query_select_related.book",
1312 | "pk": 77,
1313 | "fields": {
1314 | "title": "a",
1315 | "author": 77
1316 | }
1317 | },
1318 | {
1319 | "model": "query_select_related.book",
1320 | "pk": 78,
1321 | "fields": {
1322 | "title": "a",
1323 | "author": 78
1324 | }
1325 | },
1326 | {
1327 | "model": "query_select_related.book",
1328 | "pk": 79,
1329 | "fields": {
1330 | "title": "a",
1331 | "author": 79
1332 | }
1333 | },
1334 | {
1335 | "model": "query_select_related.book",
1336 | "pk": 80,
1337 | "fields": {
1338 | "title": "a",
1339 | "author": 80
1340 | }
1341 | },
1342 | {
1343 | "model": "query_select_related.book",
1344 | "pk": 81,
1345 | "fields": {
1346 | "title": "a",
1347 | "author": 81
1348 | }
1349 | },
1350 | {
1351 | "model": "query_select_related.book",
1352 | "pk": 82,
1353 | "fields": {
1354 | "title": "a",
1355 | "author": 82
1356 | }
1357 | },
1358 | {
1359 | "model": "query_select_related.book",
1360 | "pk": 83,
1361 | "fields": {
1362 | "title": "a",
1363 | "author": 83
1364 | }
1365 | },
1366 | {
1367 | "model": "query_select_related.book",
1368 | "pk": 84,
1369 | "fields": {
1370 | "title": "a",
1371 | "author": 84
1372 | }
1373 | },
1374 | {
1375 | "model": "query_select_related.book",
1376 | "pk": 85,
1377 | "fields": {
1378 | "title": "a",
1379 | "author": 85
1380 | }
1381 | },
1382 | {
1383 | "model": "query_select_related.book",
1384 | "pk": 86,
1385 | "fields": {
1386 | "title": "a",
1387 | "author": 86
1388 | }
1389 | },
1390 | {
1391 | "model": "query_select_related.book",
1392 | "pk": 87,
1393 | "fields": {
1394 | "title": "a",
1395 | "author": 87
1396 | }
1397 | },
1398 | {
1399 | "model": "query_select_related.book",
1400 | "pk": 88,
1401 | "fields": {
1402 | "title": "a",
1403 | "author": 88
1404 | }
1405 | },
1406 | {
1407 | "model": "query_select_related.book",
1408 | "pk": 89,
1409 | "fields": {
1410 | "title": "a",
1411 | "author": 89
1412 | }
1413 | },
1414 | {
1415 | "model": "query_select_related.book",
1416 | "pk": 90,
1417 | "fields": {
1418 | "title": "a",
1419 | "author": 90
1420 | }
1421 | },
1422 | {
1423 | "model": "query_select_related.book",
1424 | "pk": 91,
1425 | "fields": {
1426 | "title": "a",
1427 | "author": 91
1428 | }
1429 | },
1430 | {
1431 | "model": "query_select_related.book",
1432 | "pk": 92,
1433 | "fields": {
1434 | "title": "a",
1435 | "author": 92
1436 | }
1437 | },
1438 | {
1439 | "model": "query_select_related.book",
1440 | "pk": 93,
1441 | "fields": {
1442 | "title": "a",
1443 | "author": 93
1444 | }
1445 | },
1446 | {
1447 | "model": "query_select_related.book",
1448 | "pk": 94,
1449 | "fields": {
1450 | "title": "a",
1451 | "author": 94
1452 | }
1453 | },
1454 | {
1455 | "model": "query_select_related.book",
1456 | "pk": 95,
1457 | "fields": {
1458 | "title": "a",
1459 | "author": 95
1460 | }
1461 | },
1462 | {
1463 | "model": "query_select_related.book",
1464 | "pk": 96,
1465 | "fields": {
1466 | "title": "a",
1467 | "author": 96
1468 | }
1469 | },
1470 | {
1471 | "model": "query_select_related.book",
1472 | "pk": 97,
1473 | "fields": {
1474 | "title": "a",
1475 | "author": 97
1476 | }
1477 | },
1478 | {
1479 | "model": "query_select_related.book",
1480 | "pk": 98,
1481 | "fields": {
1482 | "title": "a",
1483 | "author": 98
1484 | }
1485 | },
1486 | {
1487 | "model": "query_select_related.book",
1488 | "pk": 99,
1489 | "fields": {
1490 | "title": "a",
1491 | "author": 99
1492 | }
1493 | },
1494 | {
1495 | "model": "query_select_related.book",
1496 | "pk": 100,
1497 | "fields": {
1498 | "title": "a",
1499 | "author": 100
1500 | }
1501 | }
1502 | ]
1503 |
--------------------------------------------------------------------------------