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 functions format() , 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 keys , values. keyword form of function calling introduces overhead. in addition, seems grabbing uses pyobject_getitem incurs overhead due generic nature.


Comments

Popular posts from this blog

account - Script error login visual studio DefaultLogin_PCore.js -

xcode - CocoaPod Storyboard error: -