python - 为什么startswith比slicing慢

标签 python startswith

为什么要执行startwith比切片还慢?

In [1]: x = 'foobar'

In [2]: y = 'foo'

In [3]: %timeit x.startswith(y)
1000000 loops, best of 3: 321 ns per loop

In [4]: %timeit x[:3] == y
10000000 loops, best of 3: 164 ns per loop

令人惊讶的是,即使包括长度的计算,切片仍然显得更快:

In [5]: %timeit x[:len(y)] == y
1000000 loops, best of 3: 251 ns per loop

注意:此行为的第一部分在 Python for Data Analysis 中注明。 (第 3 章),但没有提供任何解释。

.

如果有帮助:here is the C code for startswith ;这是dis.dis的输出:

In [6]: import dis

In [7]: dis_it = lambda x: dis.dis(compile(x, '<none>', 'eval'))

In [8]: dis_it('x[:3]==y')
  1           0 LOAD_NAME                0 (x)
              3 LOAD_CONST               0 (3)
              6 SLICE+2             
              7 LOAD_NAME                1 (y)
             10 COMPARE_OP               2 (==)
             13 RETURN_VALUE        

In [9]: dis_it('x.startswith(y)')
  1           0 LOAD_NAME                0 (x)
              3 LOAD_ATTR                1 (startswith)
              6 LOAD_NAME                2 (y)
              9 CALL_FUNCTION            1
             12 RETURN_VALUE 

最佳答案

一些性能差异可以通过考虑 . 操作符执行其操作所花费的时间来解释:

>>> x = 'foobar'
>>> y = 'foo'
>>> sw = x.startswith
>>> %timeit x.startswith(y)
1000000 loops, best of 3: 316 ns per loop
>>> %timeit sw(y)
1000000 loops, best of 3: 267 ns per loop
>>> %timeit x[:3] == y
10000000 loops, best of 3: 151 ns per loop

另一部分差异可以通过 startswith 是一个函数这一事实来解释,即使是无操作函数调用也需要一些时间:

>>> def f():
...     pass
... 
>>> %timeit f()
10000000 loops, best of 3: 105 ns per loop

这并没有完全解释差异,因为使用切片和 len 的版本调用了一个函数并且仍然更快(与 sw(y) 上面 -- 267 ns):

>>> %timeit x[:len(y)] == y
1000000 loops, best of 3: 213 ns per loop

我在这里唯一的猜测是,也许 Python 优化了内置函数的查找时间,或者 len 调用被高度优化(这可能是真的)。可以使用自定义的 len 函数对其进行测试。或者可能这就是 LastCoder 所识别的差异所在。开始。另请注意larsmans ' 结果,这表明 startswith 对于较长的字符串实际上更快。上面的全部推理仅适用于我所说的开销实际上很重要的那些情况。

关于python - 为什么startswith比slicing慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13270888/

相关文章:

python - 使用涉及积分的方程提高 scipy.optimize.fsolve 的精度

python - 使用 python 登录网站并进行网页抓取

python - 如何删除Python输入中的空格

python - 在图例文本中与 Latex 一起使用 matplotlib 散点标记

python - 获取一种语法来读取文本中的多个关键字

Python GeoIP2 地址未找到错误

python - 在Python中,有什么理由比字符串切片更喜欢startswith吗?

c# - 为什么这个字符串 ("ʿAbdul-Baha' "^^mso :text@de) doesn't start with "?

c# - String.StartsWith 使用 StringComparison.OrdinalIgnoreCase 的性能

powershell - 我无法使用 Powershell StartsWith 函数