所以这是一个CPython的东西,不太确定它与其他实现有相同的行为。
但'{0}'.format()
比str()
和'{}'.format()
快。我发布了来自 Python 3.5.2 的结果,但是,我尝试使用 Python 2.7.12 并且趋势是相同的。
%timeit q=['{0}'.format(i) for i in range(100, 100000, 100)]
%timeit q=[str(i) for i in range(100, 100000, 100)]
%timeit q=['{}'.format(i) for 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
object.__str__(self)
上的docs
由
str(object)
和内置函数format()
和print()
调用,以计算对象的“非正式”或可打印的字符串表示形式。
因此,str()
和format()
调用相同的object.__str__(self)
方法,但速度的差异来自哪里?
更新
正如@StefanPochmann和@Leon在评论中指出的那样,他们会得到不同的结果。我尝试使用python -m timeit "..."
运行它,它们是正确的,因为结果是:
$ python3 -m timeit "['{0}'.format(i) for i in range(100, 100000, 100)]"
1000 loops, best of 3: 441 usec per loop
$ python3 -m timeit "[str(i) for i in range(100, 100000, 100)]"
1000 loops, best of 3: 297 usec per loop
$ python3 -m timeit "['{}'.format(i) for i in range(100, 100000, 100)]"
1000 loops, best of 3: 420 usec per loop
所以看来IPython正在做一些奇怪的事情......
新问题:什么是速度将对象转换为str
的首选方法?
答案 0 :(得分:7)
由于某些原因,IPython时序刚刚关闭(但是,当在不同的单元格中使用较长格式的字符串进行测试时,它表现得略好)。也许在同一个细胞中执行是不对的,不是真的知道。
无论哪种方式,"{}"
比"{pos}"
快一点,速度比"{name}"
快,而str
慢于str(val)
。
str
是将对象转换为__str__
的最快方法;它直接调用对象' format
,如果存在,则返回结果字符串。其他的,如str.format
,(或format
)包含额外的开销,因为额外的函数调用(到__str__
本身);处理任何参数,解析格式字符串,然后然后调用args
的{{1}}。
对于str.format
方法,"{}"
使用自动编号;来自docs on the format syntax的一小部分:
版本3.1中更改:位置参数说明符可以省略,因此
'{} {}'
等同于'{0} {1}'
。
即,如果您提供以下形式的字符串:
"{}{}{}".format(1, 2, 3)
CPython 马上知道这等同于:
"{0}{1}{2}".format(1, 2, 3)
使用包含表示位置的数字的格式字符串; CPython不能假设一个严格增加的数字(从0
开始)并且必须解析每一个括号以使其正确,在此过程中减慢一些事情:
"{1}{2}{0}".format(1, 2, 3)
这也是为什么不允许将这两者混合在一起的原因:
"{1}{}{2}".format(1, 2, 3)
当你尝试这样做时,你会得到一个很好的ValueError
:
ValueError: cannot switch from automatic field numbering to manual field specification
它还抓住了这些positionals with PySequence_GetItem
,至少与PyObject_GetItem
[见下一步]相比,我确信它很快。
对于"{name}"
值,CPython总是有额外的工作要做,因为我们处理关键字参数而不是位置参数;这包括为调用构建字典以及为加载LOAD
和值生成更多key
字节代码指令的方法。函数调用的关键字形式总是会引入一些开销。此外,似乎抓取实际上使用了PyObject_GetItem
,由于其通用性质,会产生一些额外的开销。