A very common mistake that 's made by many developers is optimizing the code continuously from the very beginning. This is often a pointless and wasteful endeavor because the real bottlenecks are often located where you would have never thought they would be.
Even a seemingly simple application is usually composed of very complex interactions, and it is often impossible to guess how well it will behave until it is actually used by its users in the real production environment.
Of course, this is not a reason to write every function and algorithm with total negligence of performance problems and solve every problem by brute forcing it. Some performance hot spots of your application may be obvious from the very beginning, and therefore it makes sense to use performant solutions at an early stage of development. But you should do it very carefully and try to keep your code as simple as possible at all times. Your main goal should always be to make your code work first. This goal should not be hindered by optimization efforts.
For line-level code, the Python philosophy is that there's one and preferably only one way to do it. So, as long as you stick with a Pythonic syntax, as described in Chapter 3, Modern Syntax Elements - Below the Class Level, and Chapter 4, Modern Syntax Elements - Above the Class Level, your code (in the micro scale) should be fine. Often, writing less code is better and faster than writing more code.
Until your code works and is ready to be profiled, you should avoid the following practices:
- Any kind of caching or value memoization, even if it's a simple global dictionary
- Externalizing a part of the code in C or hybrid languages, such as Cython
- Using specialized external libraries that are focused mainly on performance optimization
Keep in mind that these are not strict rules. If doing any of the preceding things will, in the end, result in code that is simpler and more readable, you should definitely do that. Sometimes, using libraries like NumPy might ease the development of specific features and produce simpler and faster code in the end. Furthermore, you should not rewrite a function if there is a good library that does it for you. Also, for some very specialized areas, such as scientific calculation or computer games, the usage of specialized libraries and modules written using different languages might also be unavoidable from the beginning.
For instance, Soya 3D, which is a game engine on top of OpenGL (see http://home.gna.org/oomadness/en/soya3d/index.html), uses C and Pyrex for fast matrix operations when rendering real-time 3D.
Make it work, then make it right, then make it fast".
In the next section, we will take a look at how things work from the user's point of view.