constant in python?

Skip Montanaro skip at pobox.com
Sat Aug 18 14:15:24 EDT 2001


    >> IMHO constants are useful in compiled languages because they are
    >> immutable and therefore a compiler can insert them as "in-line"
    >> operands for optimization.

    Alex> Sure, no doubt you can gain a microsecond or two each time a
    Alex> constant is a literal rather than having to be fetched anew from
    Alex> the module owning it.  But, so what?!  Any good Python developer
    Alex> using a module attribute (that is not meant to change) in a tight
    Alex> loop that'a performance hot-spot would surely 'hoist' the module
    Alex> access out of the loop, using a local function variable instead
    Alex> (which is just as fast to access as a literal).

I'll add a couple things to reinforce Alex's arguments.  One, see PEP 0266
for a possible solution to this particular performance problem, small though
it is.  Two, constant literals used within a function, e.g., the "5" in this
function:

    def f(a):
        return a+5

are accessed no faster than local variables the way the current virtual
machine works.  Constant literals do not appear in the instruction stream
itself.  They are stored in a per-function array of constants which is
accessed with roughly the same speed as the local variables array.  In fact,
some things you'd naively think would be faster (because they would be in
most any similar C program), such as

    def f(a):
        return a+(1.0+8j)

are actually slower, because the compiler currently generates two constant
loads and an add.  (Same thing applies for tuples of constants.)

    Alex> The design of the Python language is *NOT* traditionally driven by
    Alex> an obsession with micro-optimizations -- thanks be, or it would
    Alex> most definitely _NOT_ be Python.  These misplaced performance-
    Alex> related worries surely can't justify perverting the language by
    Alex> adding a built-in "constant".

Agreed.  There are far more important things to worry about performance-
wise.  Consider, for example, the table of dynamic opcode frequencies
Marc-Andre Lemburg posted to python-dev in July 2000:

    http://mail.python.org/pipermail/python-dev/2000-July/007609.html

Ignore the SET_LINENO counts because "python -O" already zaps them.  Of the
remaining opcodes in his table, roughly 65% of them do nothing but move data
onto, off of, or within the stack.  I consider all the following as data
movement opcodes: LOAD_FAST, LOAD_CONST, LOAD_NAME, LOAD_GLOBAL, STORE_FAST,
POP_TOP, LOAD_ATTR, STORE_NAME, and STORE_ATTR.

If you want some performance boost, think about ways you might delete about
90% of those instructions. ;-)

-- 
Skip Montanaro (skip at pobox.com)
http://www.mojam.com/
http://www.musi-cal.com/




More information about the Python-list mailing list