performance.txt 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. ============================
  2. Performance and optimization
  3. ============================
  4. This document provides an overview of techniques and tools that can help get
  5. your Django code running more efficiently - faster, and using fewer system
  6. resources.
  7. Introduction
  8. ============
  9. Generally one's first concern is to write code that *works*, whose logic
  10. functions as required to produce the expected output. Sometimes, however, this
  11. will not be enough to make the code work as *efficiently* as one would like.
  12. In this case, what's needed is something - and in practice, often a collection
  13. of things - to improve the code's performance without, or only minimally,
  14. affecting its behavior.
  15. General approaches
  16. ==================
  17. What are you optimizing *for*?
  18. ------------------------------
  19. It's important to have a clear idea what you mean by 'performance'. There is
  20. not just one metric of it.
  21. Improved speed might be the most obvious aim for a program, but sometimes other
  22. performance improvements might be sought, such as lower memory consumption or
  23. fewer demands on the database or network.
  24. Improvements in one area will often bring about improved performance in
  25. another, but not always; sometimes one can even be at the expense of another.
  26. For example, an improvement in a program's speed might cause it to use more
  27. memory. Even worse, it can be self-defeating - if the speed improvement is so
  28. memory-hungry that the system starts to run out of memory, you'll have done
  29. more harm than good.
  30. There are other trade-offs to bear in mind. Your own time is a valuable
  31. resource, more precious than CPU time. Some improvements might be too difficult
  32. to be worth implementing, or might affect the portability or maintainability of
  33. the code. Not all performance improvements are worth the effort.
  34. So, you need to know what performance improvements you are aiming for, and you
  35. also need to know that you have a good reason for aiming in that direction -
  36. and for that you need:
  37. Performance benchmarking
  38. ------------------------
  39. It's no good just guessing or assuming where the inefficiencies lie in your
  40. code.
  41. Django tools
  42. ^^^^^^^^^^^^
  43. `django-debug-toolbar
  44. <https://github.com/django-debug-toolbar/django-debug-toolbar/>`_ is a very
  45. handy tool that provides insights into what your code is doing and how much
  46. time it spends doing it. In particular it can show you all the SQL queries your
  47. page is generating, and how long each one has taken.
  48. Third-party panels are also available for the toolbar, that can (for example)
  49. report on cache performance and template rendering times.
  50. Third-party services
  51. ^^^^^^^^^^^^^^^^^^^^
  52. There are a number of free services that will analyse and report on the
  53. performance of your site's pages from the perspective of a remote HTTP client,
  54. in effect simulating the experience of an actual user.
  55. These can't report on the internals of your code, but can provide a useful
  56. insight into your site's overall performance, including aspects that can't be
  57. adequately measured from within Django environment. Examples include:
  58. * `Yahoo's Yslow <http://developer.yahoo.com/yslow/>`_
  59. * `Google PageSpeed <https://developers.google.com/speed/pagespeed/>`_
  60. There are also several paid-for services that perform a similar analysis,
  61. including some that are Django-aware and can integrate with your codebase to
  62. profile its performance far more comprehensively.
  63. Get things right from the start
  64. -------------------------------
  65. Some work in optimization involves tackling performance shortcomings, but some
  66. of the work can simply be built in to what you'd do anyway, as part of the good
  67. practices you should adopt even before you start thinking about improving
  68. performance.
  69. In this respect Python is an excellent language to work with, because solutions
  70. that look elegant and feel right usually are the best performing ones. As with
  71. most skills, learning what "looks right" takes practice, but one of the most
  72. useful guidelines is:
  73. Work at the appropriate level
  74. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  75. Django offers many different ways of approaching things, but just because it's
  76. possible to do something in a certain way doesn't mean that it's the most
  77. appropriate way to do it. For example, you might find that you could calculate
  78. the same thing - the number of items in a collection, perhaps - in a
  79. ``QuerySet``, in Python, or in a template.
  80. However, it will almost always be faster to do this work at lower rather than
  81. higher levels. At higher levels the system has to deal with objects through
  82. multiple levels of abstraction and layers of machinery.
  83. That is, the database can typically do things faster than Python can, which can
  84. do them faster than the template language can::
  85. # QuerySet operation on the database
  86. # fast, because that's what databases are good at
  87. my_bicycles.count()
  88. # counting Python objects
  89. # slower, because it requires a database query anyway, and processing
  90. # of the Python objects
  91. len(my_bicycles)
  92. # Django template filter
  93. # slower still, because it will have to count them in Python anyway,
  94. # and because of template language overheads
  95. {{ my_bicycles|length }}
  96. Generally speaking, the most appropriate level for the job is the lowest-level
  97. one that it is comfortable to code for.
  98. .. note::
  99. The example above is merely illustrative.
  100. Firstly, in a real-life case you need to consider what is happening before
  101. and after your count to work out what's an optimal way of doing it *in that
  102. particular context*. The database optimization documents describes :ref:`a
  103. case where counting in the template would be better
  104. <overuse_of_count_and_exists>`.
  105. Secondly, there are other options to consider: in a real-life case, ``{{
  106. my_bicycles.count }}``, which invokes the ``QuerySet`` ``count()`` method
  107. directly from the template, might be the most appropriate choice.
  108. Caching
  109. =======
  110. Often it is expensive (that is, resource-hungry and slow) to compute a value,
  111. so there can be huge benefit in saving the value to a quickly accessible cache,
  112. ready for the next time it's required.
  113. It's a sufficiently significant and powerful technique that Django includes a
  114. comprehensive caching framework, as well as numerous other opportunities to
  115. make use of caching.
  116. :doc:`The caching framework </topics/cache>`
  117. --------------------------------------------
  118. Django's :doc:`caching framework </topics/cache>` offers very significant
  119. opportunities for performance gains, by saving dynamic content so that it
  120. doesn't need to be calculated for each request.
  121. For convenience, Django offers different levels of cache granularity: you can
  122. cache the output of specific views, or only the pieces that are difficult to
  123. produce, or even an entire site.
  124. Implementing caching should not be regarded as an alternative to improving code
  125. that's performing poorly because it has been written badly. It's one of the
  126. final steps towards producing well-performing code, not a shortcut.
  127. Other opportunities for caching
  128. -------------------------------
  129. Beyond the caching framework, Django offers other smaller pieces of caching
  130. functionality.
  131. :class:`~django.utils.functional.cached_property`
  132. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  133. It's common to have to call a class instances's method more than once. If
  134. that function is expensive, then doing so can be wasteful.
  135. Using the ``@cached_property`` decorator saves the value returned by a
  136. property; the next time the function is called on that instance, it will return
  137. the saved value rather than re-computing it. Note that this only works on
  138. methods that take ``self`` as their only argument and that it changes the
  139. method to a property.
  140. :class:`~django.contrib.staticfiles.storage.CachedStaticFilesStorage`
  141. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  142. :class:`~django.contrib.staticfiles.storage.CachedStaticFilesStorage` appends a
  143. content-dependent tag to the filenames of :doc:`static files
  144. </ref/contrib/staticfiles>` to make it safe for browsers to cache them
  145. long-term without missing future changes - when a file changes, so will the
  146. tag, so browsers will reload the asset automatically.
  147. Understanding laziness
  148. ======================
  149. *Laziness* is a strategy complementary to caching. Caching avoids
  150. recomputation by saving results; laziness delays computation until it's
  151. actually required.
  152. Laziness allows us to refer to things before they are instantiated, or even
  153. before it's possible to instantiate them. This has numerous uses.
  154. For example, :ref:`lazy translation <lazy-translations>` can be used before the
  155. target language is even known, because it doesn't take place until the
  156. translated string is actually required, such as in a rendered template.
  157. Laziness is also a way to save effort by trying to avoid work in the first
  158. place. That is, one aspect of laziness is not doing anything until it has to be
  159. done, because it may not turn out to be necessary after all. Laziness can
  160. therefore have performance implications, and the more expensive the work
  161. concerned, the more there is to gain through laziness.
  162. Python provides a number of tools for lazy evaluation, particularly through the
  163. :py:term:`generator` and :py:term:`generator expression` constructs. It's worth
  164. reading up on laziness in Python to discover opportunities for making use of
  165. lazy patterns in your code.
  166. Laziness in Django
  167. ------------------
  168. Django is itself quite lazy. A good example of this can be found in the
  169. evaluation of ``QuerySets``. :ref:`QuerySets are lazy <querysets-are-lazy>`.
  170. Thus a ``QuerySet`` can be created, passed around and combined with other
  171. ``QuerySets``, without actually incurring any trips to the database to fetch
  172. the items it describes. What gets passed around is the ``QuerySet`` object, not
  173. the collection of items that - eventually - will be required from the database.
  174. On the other hand, :ref:`certain operations will force the evaluation of a
  175. QuerySet <when-querysets-are-evaluated>`. Avoiding the premature evaluation of
  176. a ``QuerySet`` can save making an expensive and unnecessary trip to the
  177. database.
  178. Django also offers an :meth:`~django.utils.functional.allow_lazy` decorator.
  179. This allows a function that has been called with a lazy argument to behave
  180. lazily itself, only being evaluated when it needs to be. Thus the lazy argument
  181. - which could be an expensive one - will not be called upon for evaluation
  182. until it's strictly required.
  183. Databases
  184. =========
  185. :doc:`Database optimization </topics/db/optimization>`
  186. ------------------------------------------------------
  187. Django’s database layer provides various ways to help developers get the best
  188. performance from their databases. The :doc:`database optimization documentation
  189. </topics/db/optimization>` gathers together links to the relevant
  190. documentation and adds various tips that outline the steps to take when
  191. attempting to optimize your database usage.
  192. Other database-related tips
  193. ---------------------------
  194. Enabling :ref:`persistent-database-connections` can speed up connections to the
  195. database accounts for a significant part of the request processing time.
  196. This helps a lot on virtualized hosts with limited network performance, for example.
  197. HTTP performance
  198. ================
  199. Middleware
  200. ----------
  201. Django comes with a few helpful pieces of :doc:`middleware </ref/middleware>`
  202. that can help optimize your site's performance. They include:
  203. :class:`~django.middleware.http.ConditionalGetMiddleware`
  204. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  205. Adds support for modern browsers to conditionally GET responses based on the
  206. ``ETag`` and ``Last-Modified`` headers.
  207. :class:`~django.middleware.gzip.GZipMiddleware`
  208. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  209. Compresses responses for all modern browsers, saving bandwidth and transfer
  210. time. Note that GZipMiddleware is currently considered a security risk, and is
  211. vulnerable to attacks that nullify the protection provided by TLS/SSL. See the
  212. warning in :class:`~django.middleware.gzip.GZipMiddleware` for more information.
  213. Third-party HTTP tools
  214. ----------------------
  215. There are numerous third-party Django tools and packages available, notably
  216. ones that are able to "minify" and compress HTML, CSS and JavaScript.
  217. Template performance
  218. ====================
  219. Note that:
  220. * using ``{% block %}`` is faster than using ``{% include %}``
  221. * heavily-fragmented templates, assembled from many small pieces, can affect
  222. performance
  223. The cached template loader
  224. --------------------------
  225. Enabling the :class:`cached template loader
  226. <django.template.loaders.cached.Loader>` often improves performance
  227. drastically, as it avoids compiling each template every time it needs to be
  228. rendered.
  229. Using different versions of available software
  230. ==============================================
  231. It can sometimes be worth checking whether different and better-performing
  232. versions of the software that you're using are available.
  233. This may be helpful, but is unlikely to solve a serious performance problem.
  234. You won't usually gain performance advantages that are better than marginal.
  235. .. note::
  236. It's worth repeating: **reaching for alternatives to software you're
  237. already using is very rarely the answer to performance problems**.
  238. Newer is often - but not always - better
  239. ----------------------------------------
  240. It's fairly rare for a new release of well-maintained software to be less
  241. efficient, but the maintainers can't anticipate every possible use-case - so
  242. while being aware that newer versions are likely to perform better, don't
  243. simply assume that they always will.
  244. This is true of Django itself. Successive releases have offered a number of
  245. improvements across the system, but you should still check the real-world
  246. performance of your application, because in some cases you may find that
  247. changes mean it performs worse rather than better.
  248. Newer versions of Python, and also of Python packages, will often perform
  249. better too - but measure, rather than assume.
  250. .. note::
  251. Unless you've encountered an unusual performance problem in a particular
  252. version, you'll generally find better features, reliability, and security
  253. in a new release and that these benefits are far more significant than any
  254. performance you might win or lose.
  255. Alternatives to Django's template language
  256. ------------------------------------------
  257. For nearly all cases, Django's built-in template language is perfectly
  258. adequate. However, if the bottlenecks in your Django project seem to lie in the
  259. template system and you have exhausted other opportunities to remedy this, a
  260. third-party alternative may be the answer.
  261. `Jinja2 <http://jinja.pocoo.org/docs/>`_ can offer performance improvements,
  262. particularly when it comes to speed.
  263. Alternative template systems vary in the extent to which they share Django's
  264. templating language.
  265. .. note::
  266. *If* you experience performance issues in templates, the first thing to do
  267. is to understand exactly why. Using an alternative template system may
  268. prove faster, but the same gains may also be available without going to
  269. that trouble - for example, expensive processing and logic in your
  270. templates could be done more efficiently in your views.
  271. Alternative software implementations
  272. ------------------------------------
  273. It *may* be worth checking whether Python software you're using has been
  274. provided in a different implementation that can execute the same code faster.
  275. However, most Django performance problems in well-written code are typically
  276. not to be found at the Python execution level, but rather in inefficient
  277. database querying, caching, and templates (and if you're relying on
  278. poorly-written Python code, your performance problems are very unlikely to be
  279. solved by having it execute faster).
  280. Avoid using C implementations of Python libraries or non-standard Python
  281. implementations like `PyPy <http://pypy.org/>`_ in search of performance gains,
  282. unless you are sure they are appropriate for your application. Any gains are
  283. likely to be small, and compatibility issues are common.