【问题标题】:Why is hexifying strings with % faster than hexifying with f strings?为什么用 % 对字符串进行 hexifying 比用 f 个字符串进行hexifying 快?
【发布时间】:2017-09-11 18:42:56
【问题描述】:

所以我一直在比较不同场景中的 f 弦和它们的速度。我遇到了一个 f 字符串速度较慢的场景。

编辑:x = 0

In[1]: %timeit f"{x:0128x}"
363 ns ± 1.69 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In[2]: %timeit '%0128x' % x
224 ns ± 1.37 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In[3]: %timeit f"{x:0128X}"
533 ns ± 22 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In[4]: %timeit "%0128X" % x
222 ns ± 0.408 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

为什么在这种情况下 f-strings 慢,为什么 f-strings 的 'X' 比 'x' 慢很多?

【问题讨论】:

  • 附注:如果原始值 x 是整数,我不确定标题是否应该是“十六进制字符串”。
  • 或许更好的表述方式是“使用十六进制格式”
  • 您可以编辑标题。
  • 因为一个 (f-strings) 比另一个复杂得多。
  • 请注意,您应该避免使用不同的范围。 % x 使用 x 作为本地,f"..." 很可能正在查找 x 作为全局。将两者放在一个函数中以确保相同的范围。然后我得到每个循环 430ns 和 304ns。

标签: python performance python-3.x string-formatting python-3.6


【解决方案1】:

%x(和其他数字转换)的字符串插值不能重载,因此解释器可以快速执行。

f-strings 和format() 内置函数一样,需要在对象上寻找__format__ 方法。这比较慢。

例如,这个类可以覆盖%sformat(),但不能覆盖%x

class myint(int):
    def __format__(self, spec):
        return "example"
    def __int__(self):
        return "example"
    def __str__(self):
        return "example"
    def __repr__(self):
        return "example"
>>> '%x' % myint()
'0'

大写字符串,在 CPython 实现中,首先构建小写字符串,然后循环遍历字符串以更改大小写。

覆盖__str__,即使返回一个常量字符串,也会使%s%x慢,因为它涉及到一个方法调用。

【讨论】:

  • 感谢您的洞察力。我认为最大的问题是这些函数如何寻找原始的x 值。由于我上面展示的测试将 x 作为预先声明,因此它显示的数字与将 x 设置为局部变量大不相同。
猜你喜欢
  • 2017-12-03
  • 1970-01-01
  • 2014-09-03
  • 2015-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-29
  • 2019-07-03
相关资源
最近更新 更多