May 14, 2021 Django
Usually a person's first concern is writing code that produces the expected output as needed. Sometimes, however, this is not enough to make your code work efficiently.
In this case, what is needed is something - actually, usually a series of things - that can improve the performance of the code without, or affect, the behavior of the code in the smallest way.
It is important to have a clear understanding of what "performance" means. There is not only one indicator.
Speed increases may be the most obvious goal for your program, but you may sometimes seek other performance improvements, such as reducing memory consumption or reducing the need for databases or networks.
Improvements in one area usually lead to improvements in the other, but not always; F or example, an increase in program speed may cause it to use more memory. Worse, it can be self-deception - if the speed increase is so memory-consuming that the system starts to run out of memory, you're doing more harm than good.
There are other trade-offs. Y our own time is a valuable resource, more valuable than CPU time. S ome improvements may be too difficult to implement, or may affect the portability or maintainability of your code. Not all performance improvements are worth the effort.
Therefore, you need to know what performance improvements to implement, and you need to know that there are good reasons to aim in this direction - and you need to:
It's no use just guessing or assuming inefficiencies in your code.
django-debug-toolbar is a handy tool that provides insight into what your code is doing and how much time it takes. In particular, it displays all SQL queries generated by the page and how long each query took.
The toolbar can also use a third side board that can, for example, report cache performance and template rendering time.
There are many free services that analyze and report the performance of site pages from the perspective of remote HTTP clients, and are actually simulating the actual user experience.
These do not report inside your code, but provide useful insights into the overall performance of your site, including aspects that cannot be adequately measured in a Django environment. Examples include:
There are also paid services that perform similar analysis, including some that support Django, which integrates with your code base to analyze its performance more comprehensively.
Some of the work on optimization involves addressing performance defects, but some work can also be built into what you want to do, which is part of a good practice that you should adopt even before you start thinking about improving performance.
Python is a great language for this, because a solution that looks good and feels right is usually the best performing solution. As with most skills, learning something that "looks right" requires practice, but one of the most useful guidelines is:
Django offers many different ways of dealing with it, but just because you can do something in one way doesn't mean it's the most appropriate way. For example, you might find that you can calculate the same thing in QurySet, Python, or template - the number of items in the collection, perhaps.
However, it is almost always faster to do this at a lower level than at a higher level. At a higher level, the system must handle objects through multiple layers of abstraction and machine hierarchy.
That is, databases can typically complete tasks faster than Python, and Python can accomplish tasks faster than template languages:
# QuerySet operation on the database # fast, because that's what databases are good at my_bicycles.count() # counting Python objects # slower, because it requires a database query anyway, and processing # of the Python objects len(my_bicycles) # Django template filter # slower still, because it will have to count them in Python anyway, # and because of template language overheads {{ my_bicycles|length }}
In general, the level that works best for the job is the lowest level that is appropriate for writing code.
Attention
The example above is only indicative.
First, in real life, you need to consider what happens before and after counting to find the best way to do this in a particular situation. The database optimization document describes a situation in which the count in the template is better.
Second, there are other options to consider: in practice, calling methods directly from a template may be the most appropriate option. { { my_bicycles.count }} QuerySet count()
In general, calculating values is expensive (i.e., resource-intensive and slow), so saving values to a cache that is quickly accessible for the next time you use them can be a huge benefit.
Django's well-established caching framework and other smaller caching capabilities are an important and powerful enough technique.
Django's caching framework provides a very important opportunity to improve performance by saving dynamic content, so you don't have to calculate for each request.
For convenience, Django provides different levels of cache granularity: you can cache the output of a particular view, or you can cache only fragments that are difficult to generate, or even the entire site.
Implementing caching should not be seen as an alternative to improving underperforming code because of its poor write quality. This is one of the final steps in generating good-performing code, not a shortcut.
The method of a class instance must usually be called more than once. If the feature is expensive, it can be wasteful.
Use cached_property decorator to save the value returned by the property. T he next time the function is called on the instance, it returns the saved value instead of recalculating it. Note that this applies only to methods that use self parameters as unique parameters and change the method to a property.
Some Django components also have their own caching capabilities;
Laziness is a complementary strategy to caching. T he cache avoids recalculation by saving the results. Laziness delays calculation until it is really needed.
Inertia allows us to reference them before instantiation, even before they are possible. This has many uses.
For example, you can use lazy translation before you even know the target language, because it doesn't happen until you really need a translated string, such as in a rendered template.
Laziness is also a way to save energy by avoiding work in the first way. T hat is to say, one aspect of laziness is what to do until it must be done, because after all, it may not be necessary. As a result, laziness can affect performance, and the higher the cost of the work involved, the greater the benefit of laziness.
Python provides many tools for lazy evaluation, especially through generator and generator expression construction. It's worth reading Python's inertia to discover opportunities to use lazy patterns in your code.
Django himself is lazy. A good example can be found in the assessment of QueenSets. Q uerySet is lazy. A s a result, QuerySets can be created, passed, and combined with other objects using QuerySets without actually having any database access to get the items it describes. The QurySet object is passed, not the collection of items that the database ultimately needs.
On the other hand, some actions force the evaluation of QueenSet. Avoiding premature evaluation of a QuerySet can save expensive and unnecessary travel to the database.
Django also offers a keep_lazy () decorator. T his allows functions called with lazy parameters to appear lazy in themselves and are evaluated only when needed. Therefore, lazy parameters (which can be expensive) are not invoked for evaluation until they are strictly required.
Django's database layer provides a variety of ways to help developers get the best performance from their databases. The database optimizes document aggregation links to related files and adds various techniques that outline the steps taken when trying to optimize database usage.
Enabling persistent connections speeds up connections to database accounts for most request processing times.
For example, this can be of great help to virtual hosts with limited network performance.
Django comes with some useful middleware to help you optimize the performance of your website. They include:
Added support for modern browsers to get conditional responses based on ETag and Last-Modified headers. It also calculates and sets an ETag if needed.
Compress the response of all modern browsers, saving bandwidth and transfer time. P lease note that GZipMiddleware is currently considered a security risk and is vulnerable to attacks that invalidate the protection provided by TLS/SSL. For more information about GZipMiddleware, see Warnings.
Sessions that use caching can be a way to improve performance by avoiding loading session data from slower storage sources, such as databases, and storing frequently used session data in memory.
Static files (not dynamic by definition) are a great goal for optimizing benefits.
By taking advantage of the web browser's caching capabilities, you can completely eliminate network hits on a given file after the initial download.
ManifestStaticFilesStorage attachs a content-related tag to the file name of a static file so that the browser can safely cache them for a long time without losing future changes - when the file changes, the tag changes, so the browser will automatically reload the asset.
Several third-party Django tools and packages provide the ability to "minimize" HTML, CSS, and JavaScript. They remove unnecessary spaces, line breaks, and comments, and shorten variable names, reducing the size of documents published by the site.
Attention:
Enabling typically greatly improves performance because it avoids compiling each template every time it needs to be rendered. cached template loader
Sometimes it's worth checking the different versions of the software you're using and the better-performing versions.
These technologies are intended for more advanced users who want to push the performance limits of django sites that have been fully optimized.
However, they are not a panacea for performance issues, and they are unlikely to yield better benefits than marginal benefits for sites that have not done more basic work in the right way.
Attention
It's worth repeating that finding alternatives to the software you've used is never the first answer to performance problems. When you reach this optimization level, you need a formal benchmarking solution.
It's fairly rare for newly released well-maintained software to be less efficient, but maintenance personnel can't foresee all possible use cases - so while aware that newer versions might perform better, don't assume that they will always be.
Django himself is like this. Subsequent releases provide many improvements across the system, but you should still check the actual performance of your application, because in some cases you may find that changes mean poor performance rather than better performance.
Newer versions of Python and Python packages also tend to perform better - but measure rather than assume.
Attention
Unless you experience unusual performance issues in a particular release, you will typically find better features, reliability, and security in the new version, and these benefits are far more important than any performance you might win or lose.
In almost all cases, Django's built-in template language is sufficient. However, if the bottleneck in the Django project appears to be in the template system and you take other opportunities to resolve the issue, a third-party alternative may be the answer.
Jinja2 can improve performance, especially in terms of speed.
Alternative template systems vary in the extent to which Django template languages are shared.
Note: If you experience performance issues in a template, the first thing to do is to know exactly why. Using an alternate template system may prove faster, but you can get the same benefits without causing trouble - for example, expensive processing and logic in a template can be done more efficiently in the view.
It may be worth checking that the Python software you are using is already available in a different implementation that executes the same code faster.
However, in a well-written Django site, most performance issues are not at the Python execution level, but in terms of inefficient database queries, caching, and templates. If you rely on poorly written Python code, you can't solve performance problems by executing faster.
Using alternative implementations may introduce compatibility, deployment, portability, or maintenance issues. Needless to say, before adopting a non-standard implementation, you should ensure that it provides enough performance improvements for your application to outs trump the potential risks.
With these warnings in consideration, you should be aware that:
PyPy is Python's own Python implementation (the "standard" Python implementation in C). PyPy is typically available for heavyweight applications and can therefore significantly improve performance.
The main goal of the PyPy project is to be compatible with existing Python APIs and libraries. Django is compatible, but you need to check the compatibility of other libraries you rely on.
Some Python libraries are also implemented with C, and may be faster. T hey are designed to provide the same API. Note that compatibility issues and behavioral differences are not unknown (and are not always immediately visible).
For more information: https://docs.djangoproject.com/en/3.0/