Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a9e9abb

Browse files
committed
Issue #13528: rework the performance question in the programming FAQ
2 parents 1b7458b + 432259f commit a9e9abb

1 file changed

Lines changed: 62 additions & 153 deletions

File tree

Doc/faq/programming.rst

Lines changed: 62 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -115,159 +115,6 @@ Yes. The coding style required for standard library modules is documented as
115115
:pep:`8`.
116116

117117

118-
My program is too slow. How do I speed it up?
119-
---------------------------------------------
120-
121-
That's a tough one, in general. There are many tricks to speed up Python code;
122-
consider rewriting parts in C as a last resort.
123-
124-
`Cython <http://cython.org>`_ and `Pyrex <http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/>`_
125-
can compile a slightly modified version of Python code into a C extension, and
126-
can be used on many different platforms. Depending on your code, Cython
127-
may be able to make it significantly faster than when run by the Python
128-
interpreter.
129-
130-
The rest of this answer will discuss various tricks for squeezing a bit more
131-
speed out of Python code. *Never* apply any optimization tricks unless you know
132-
you need them, after profiling has indicated that a particular function is the
133-
heavily executed hot spot in the code. Optimizations almost always make the
134-
code less clear, and you shouldn't pay the costs of reduced clarity (increased
135-
development time, greater likelihood of bugs) unless the resulting performance
136-
benefit is worth it.
137-
138-
There is a page on the wiki devoted to `performance tips
139-
<http://wiki.python.org/moin/PythonSpeed/PerformanceTips>`_.
140-
141-
Guido van Rossum has written up an anecdote related to optimization at
142-
http://www.python.org/doc/essays/list2str.html.
143-
144-
One thing to notice is that function and (especially) method calls are rather
145-
expensive; if you have designed a purely OO interface with lots of tiny
146-
functions that don't do much more than get or set an instance variable or call
147-
another method, you might consider using a more direct way such as directly
148-
accessing instance variables. Also see the standard module :mod:`profile` which
149-
makes it possible to find out where your program is spending most of its time
150-
(if you have some patience -- the profiling itself can slow your program down by
151-
an order of magnitude).
152-
153-
Remember that many standard optimization heuristics you may know from other
154-
programming experience may well apply to Python. For example it may be faster
155-
to send output to output devices using larger writes rather than smaller ones in
156-
order to reduce the overhead of kernel system calls. Thus CGI scripts that
157-
write all output in "one shot" may be faster than those that write lots of small
158-
pieces of output.
159-
160-
Also, be sure to use Python's core features where appropriate. For example,
161-
slicing allows programs to chop up lists and other sequence objects in a single
162-
tick of the interpreter's mainloop using highly optimized C implementations.
163-
Thus to get the same effect as::
164-
165-
L2 = []
166-
for i in range(3):
167-
L2.append(L1[i])
168-
169-
it is much shorter and far faster to use ::
170-
171-
L2 = list(L1[:3]) # "list" is redundant if L1 is a list.
172-
173-
Note that the functionally-oriented built-in functions such as :func:`map`,
174-
:func:`zip`, and friends can be a convenient accelerator for loops that
175-
perform a single task. For example to pair the elements of two lists
176-
together::
177-
178-
>>> list(zip([1, 2, 3], [4, 5, 6]))
179-
[(1, 4), (2, 5), (3, 6)]
180-
181-
or to compute a number of sines::
182-
183-
>>> list(map(math.sin, (1, 2, 3, 4)))
184-
[0.841470984808, 0.909297426826, 0.14112000806, -0.756802495308]
185-
186-
The operation completes very quickly in such cases.
187-
188-
Other examples include the ``join()`` and ``split()`` :ref:`methods
189-
of string objects <string-methods>`.
190-
191-
For example if s1..s7 are large (10K+) strings then
192-
``"".join([s1,s2,s3,s4,s5,s6,s7])`` may be far faster than the more obvious
193-
``s1+s2+s3+s4+s5+s6+s7``, since the "summation" will compute many
194-
subexpressions, whereas ``join()`` does all the copying in one pass. For
195-
manipulating strings, use the ``replace()`` and the ``format()`` :ref:`methods
196-
on string objects <string-methods>`. Use regular expressions only when you're
197-
not dealing with constant string patterns.
198-
199-
Be sure to use the :meth:`list.sort` built-in method to do sorting, and see the
200-
`sorting mini-HOWTO <http://wiki.python.org/moin/HowTo/Sorting>`_ for examples
201-
of moderately advanced usage. :meth:`list.sort` beats other techniques for
202-
sorting in all but the most extreme circumstances.
203-
204-
Another common trick is to "push loops into functions or methods." For example
205-
suppose you have a program that runs slowly and you use the profiler to
206-
determine that a Python function ``ff()`` is being called lots of times. If you
207-
notice that ``ff()``::
208-
209-
def ff(x):
210-
... # do something with x computing result...
211-
return result
212-
213-
tends to be called in loops like::
214-
215-
list = map(ff, oldlist)
216-
217-
or::
218-
219-
for x in sequence:
220-
value = ff(x)
221-
... # do something with value...
222-
223-
then you can often eliminate function call overhead by rewriting ``ff()`` to::
224-
225-
def ffseq(seq):
226-
resultseq = []
227-
for x in seq:
228-
... # do something with x computing result...
229-
resultseq.append(result)
230-
return resultseq
231-
232-
and rewrite the two examples to ``list = ffseq(oldlist)`` and to::
233-
234-
for value in ffseq(sequence):
235-
... # do something with value...
236-
237-
Single calls to ``ff(x)`` translate to ``ffseq([x])[0]`` with little penalty.
238-
Of course this technique is not always appropriate and there are other variants
239-
which you can figure out.
240-
241-
You can gain some performance by explicitly storing the results of a function or
242-
method lookup into a local variable. A loop like::
243-
244-
for key in token:
245-
dict[key] = dict.get(key, 0) + 1
246-
247-
resolves ``dict.get`` every iteration. If the method isn't going to change, a
248-
slightly faster implementation is::
249-
250-
dict_get = dict.get # look up the method once
251-
for key in token:
252-
dict[key] = dict_get(key, 0) + 1
253-
254-
Default arguments can be used to determine values once, at compile time instead
255-
of at run time. This can only be done for functions or objects which will not
256-
be changed during program execution, such as replacing ::
257-
258-
def degree_sin(deg):
259-
return math.sin(deg * math.pi / 180.0)
260-
261-
with ::
262-
263-
def degree_sin(deg, factor=math.pi/180.0, sin=math.sin):
264-
return sin(deg * factor)
265-
266-
Because this trick uses default arguments for terms which should not be changed,
267-
it should only be used when you are not concerned with presenting a possibly
268-
confusing API to your users.
269-
270-
271118
Core Language
272119
=============
273120

@@ -938,6 +785,68 @@ What does 'UnicodeDecodeError' or 'UnicodeEncodeError' error mean?
938785
See the :ref:`unicode-howto`.
939786

940787

788+
Performance
789+
===========
790+
791+
My program is too slow. How do I speed it up?
792+
---------------------------------------------
793+
794+
That's a tough one, in general. First, here are a list of things to
795+
remember before diving further:
796+
797+
* Performance characteristics vary accross Python implementations. This FAQ
798+
focusses on :term:`CPython`.
799+
* Behaviour can vary accross operating systems, especially when talking about
800+
I/O or multi-threading.
801+
* You should always find the hot spots in your program *before* attempting to
802+
optimize any code (see the :mod:`profile` module).
803+
* Writing benchmark scripts will allow you to iterate quickly when searching
804+
for improvements (see the :mod:`timeit` module).
805+
* It is highly recommended to have good code coverage (through unit testing
806+
or any other technique) before potentially introducing regressions hidden
807+
in sophisticated optimizations.
808+
809+
That being said, there are many tricks to speed up Python code. Here are
810+
some general principles which go a long way towards reaching acceptable
811+
performance levels:
812+
813+
* Making your algorithms faster (or changing to faster ones) can yield
814+
much larger benefits than trying to sprinkle micro-optimization tricks
815+
all over your code.
816+
817+
* Use the right data structures. Study documentation for the :ref:`bltin-types`
818+
and the :mod:`collections` module.
819+
820+
* When the standard library provides a primitive for doing something, it is
821+
likely (although not guaranteed) to be faster than any alternative you
822+
may come up with. This is doubly true for primitives written in C, such
823+
as builtins and some extension types. For example, be sure to use
824+
either the :meth:`list.sort` built-in method or the related :func:`sorted`
825+
function to do sorting (and see the
826+
`sorting mini-HOWTO <http://wiki.python.org/moin/HowTo/Sorting>`_ for examples
827+
of moderately advanced usage).
828+
829+
* Abstractions tend to create indirections and force the interpreter to work
830+
more. If the levels of indirection outweigh the amount of useful work
831+
done, your program will be slower. You should avoid excessive abstraction,
832+
especially under the form of tiny functions or methods (which are also often
833+
detrimental to readability).
834+
835+
If you have reached the limit of what pure Python can allow, there are tools
836+
to take you further away. For example, `Cython <http://cython.org>`_ can
837+
compile a slightly modified version of Python code into a C extension, and
838+
can be used on many different platforms. Cython can take advantage of
839+
compilation (and optional type annotations) to make your code significantly
840+
faster than when interpreted. If you are confident in your C programming
841+
skills, you can also :ref:`write a C extension module <extending-index>`
842+
yourself.
843+
844+
.. seealso::
845+
The wiki page devoted to `performance tips
846+
<http://wiki.python.org/moin/PythonSpeed/PerformanceTips>`_.
847+
848+
.. _efficient_string_concatenation:
849+
941850
What is the most efficient way to concatenate many strings together?
942851
--------------------------------------------------------------------
943852

0 commit comments

Comments
 (0)