cpython - '{0}'.format() is faster than str() and '{}'.format() using IPython %timeit and otherwise using pure Python -
so it's cpython thing, not quite sure has same behaviour other implementations.
but '{0}'.format()
faster str()
, '{}'.format()
. i'm posting results python 3.5.2, but, tried python 2.7.12 , trend same.
%timeit q=['{0}'.format(i) in range(100, 100000, 100)] %timeit q=[str(i) in range(100, 100000, 100)] %timeit q=['{}'.format(i) in range(100, 100000, 100)] 1000 loops, best of 3: 231 µs per loop 1000 loops, best of 3: 298 µs per loop 1000 loops, best of 3: 434 µs per loop
from docs on object.__str__(self)
called
str(object)
, built-in functionsformat()
,print()
compute “informal” or nicely printable string representation of object.
so, str()
, format()
call same object.__str__(self)
method, difference in speed come from?
update @stefanpochmann , @leon noted in comments, different results. tried run python -m timeit "..."
and, right, because results are:
$ python3 -m timeit "['{0}'.format(i) in range(100, 100000, 100)]" 1000 loops, best of 3: 441 usec per loop $ python3 -m timeit "[str(i) in range(100, 100000, 100)]" 1000 loops, best of 3: 297 usec per loop $ python3 -m timeit "['{}'.format(i) in range(100, 100000, 100)]" 1000 loops, best of 3: 420 usec per loop
so seems ipython doing strange...
new question: preferred way convert object str
speed?
the ipython timing off reason (though, when tested longer format string in different cells, behaved slightly better). maybe executing in same cells isn't right, don't know.
either way, "{}"
bit faster "{pos}"
faster "{name}"
while they're slower str
.
str(val)
fastest way transform object str
; directly calls objects' __str__
, if 1 exists, , returns resulting string. others, format
, (or str.format
) include additional overhead due function call (to format
itself); handling arguments, parsing format string , then invoking __str__
of args
.
for str.format
methods "{}"
uses automatic numbering; small section in docs on format syntax:
changed in version 3.1: positional argument specifiers can omitted,
'{} {}'
equivalent'{0} {1}'
.
that is, if supply string of form:
"{}{}{}".format(1, 2, 3)
cpython immediately knows equivalent to:
"{0}{1}{2}".format(1, 2, 3)
with format string contains numbers indicating positions; cpython can't assume strictly increasing number (that starts 0
) , must parse every single bracket in order right, slowing things down bit in process:
"{1}{2}{0}".format(1, 2, 3)
that's why not allowed mix these 2 together:
"{1}{}{2}".format(1, 2, 3)
you'll nice valueerror
when attempt so:
valueerror: cannot switch automatic field numbering manual field specification
it grabs these positionals pysequence_getitem
i'm pretty sure fast, @ least, in comparison pyobject_getitem
[see next].
for "{name}"
values, cpython has work due fact we're dealing keyword arguments rather positional ones; includes things building dictionary calls , generating way more load
byte-code instructions loading key
s , values. keyword form of function calling introduces overhead. in addition, seems grabbing uses pyobject_getitem
incurs overhead due generic nature.
Comments
Post a Comment