[docs] [issue1397474] timeit execution enviroment
rurpy the second
report at bugs.python.org
Tue Jan 11 19:14:06 CET 2011
rurpy the second <rurpy at yahoo.com> added the comment:
I find the changes suggested by T Reedy and refined in the
patch by E Bendersky an improvement. However, I found the
following things confused me when reading it:
"...constructor creates a function..."
the constructor creates a Timeit instance, not a function.
There is a method on that instance that is the function but
the way it is phrased in like describing the autos coming off
a Ford production line as "steering wheels". As written, the
statement creates an immediate WTF reaction in my mind.
"...that executes the *setup* statement..."
Use of term "statement" here is confusing as that term already
has a well defined meaning in Python docs. One can't syntactically
use a statement as a function argument. Only by suspending this
confusion and reading further does one discover that "statement"
here means a string containing text of some python code or a
Use of "statement" (singular) also directly conflicts with following
information that states multiple statements are ok.
Since the synopsis line already refers to "snippets", I think
continuing to use that is better (having no preexisting conflicting
meanings) than "statement".
"...default to ``'pass'`..."
The call summary immediately above makes clear what the default
parameter values are. While fine to repeat it in text, it is not
high priority information so should be moved to later in the
"...or newlines as long as they donâ€™t contain multi-line string literals..."
What is a multi-line string literal? The Language Reference ->
Lexical Analysis -> String Literals section says nothing about
Is it "a\nb"? Or """a
'"a\nb"' actually works. '"""a
b"""' doesn't of course but it is it is also clearly not valid
python string syntax so I'm not sure that 'multi-line strings need
even be mentioned. If it is mentioned then it should be made clear
that multi-line string literals are not allowed not because timeit
doesn't like them, but because python syntax allows no way to
embed them in another string.
"...pre-defined user objects..."
What does "pre-defined" mean? Builtin? Imported from stdlib?
I would use a more explicit description here.
I also think a short explanation of *why* one needs to import
program objects in 'setup' makes it a little easier and quicker
to understand what one is doing with the import, particularly if
one is using timeit somewhere other than __main__.. Thus I
suggest expanding that section slightly.
Here is my attempt to adjust taking the above observations into
account. (Sorry, can't supply a patch since I have slow internet
connection and don't have source. Text below is just my hand edit
of the "+" lines in Eli's patch.)
Class for timing execution speed of small code snippets.
A Timeit instance will contain a function (see :meth:`Timer.timeit`)
that executes a snippet of "setup" code once and then times some
number of executions of "stmt" code . The code snippets, given as
arguments *setup* and *stmt* when creating the instance, may be
either strings or callable objects.
If a string, it may contain a python expression, statement, or
multiple statements separated by ";" or newlines. Whitespace
adhering to the usual Python indentation rules must follow any
If a callable object, (often a function), the object is called
with no arguments. Note that the timing overhead is a little
larger in this case because of the extra function calls required.
The *setup* and *stmt* parameters default to ``'pass'``.
The *timer* parameter defaults to a platform-dependent
timer function (see the module doc string).
When the *setup* and *stmt* are run, they are run in a
different namespace than that of the code that calls timeit().
To give *stmt* (whether it is a callable name or code string)
access to objects defined in the code that calls timeit,
*setup* can import any needed objects. For example, if your
code defines function testfunc(), *setup* can contain,
``from __main__ import testfunc``, and code in *stmt* can
then call testfunc.
To measure the execution time of *stmt*, use the :meth:`Timer.timeit()` method.
The :meth:`Timer.repeat()` method is a convenience to call :meth:`Timer.timeit()`
multiple times and return a list of results.
Changed in version 2.6: The stmt and setup parameters can now
also take objects.
Added the line "Whitespace adhering..." because when using backslash-n
in strings it is easy to forget about any needed indentation. Sentence
could be deleted if deemed too obvious. There may also be a better
way to phrase it; currently it might imply that some whitespace
is always neccessary if not enough attention paid to the "usual
indentation rules" phrase.
In msg116330 - Eli Bendersky (eli.bendersky) wrote:
> 1) My tests show that passing the callable instead of the string
> 'test()' actually takes longer to run.
Should the documentation promise that?
I take your word that it also takes longer than running the function's
code directly (outside a function)
The original "Changed in version 2.6" section said
| Note that the timing overhead is a little larger in this case
| [callable objects] because of the extra function calls.
Here, "the other case" is presumably the plain code but could
also be a string function call (e.g. "test()") so I suppose it
is still vacuously true in that case. Accordingly I reused the
statement above in in my suggested changes. Perhaps all three
cases (string code, string function call, callable object)
should be distinguished further and compared re overhead?
Python tracker <report at bugs.python.org>
More information about the docs