Python:为什么partition(sep)比split(sep, maxsplit=1)更快

Han*_*agi 5 python string algorithm performance cpython

我发现了一个有趣的事情,它比在分隔符之后获取整个子字符串partition更快。split我已经在 Python 3.5 和 3.6 (Cpython) 中进行了测试

\n
In [1]: s = \'validate_field_name\'\n\nIn [2]: s.partition(\'_\')[-1]\nOut[2]: \'field_name\'\n\nIn [3]: s.split(\'_\', maxsplit=1)[-1]\nOut[3]: \'field_name\'\n\nIn [4]: %timeit s.partition(\'_\')[-1]\n220 ns \xc2\xb1 1.12 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000000 loops each)\n\nIn [5]: %timeit s.split(\'_\', maxsplit=1)[-1]\n745 ns \xc2\xb1 48.8 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000000 loops each)\n\nIn [6]: %timeit s[s.find(\'_\')+1:]\n340 ns \xc2\xb1 1.44 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000000 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n

我查看了Cpython源代码,发现partition使用该FASTSEARCH算法,请参见此处。并且只有当分隔符字符串的长度大于1时才split使用,请参见此处。但我测试过 sep 字符串,哪个长度更大。我得到了同样的结果。FASTSEARCH

\n

我猜原因是partition返回一个三元素元组,而不是一个列表。

\n

我想了解更多细节。

\n

C. *_*oli 6

微基准可能会产生误导

py -m timeit "'validate_field_name'.split('_', maxsplit=1)[-1]"
1000000 loops, best of 3: 0.568 usec per loop

py -m timeit "'validate_field_name'.split('_', 1)[-1]"
1000000 loops, best of 3: 0.317 usec per loop
Run Code Online (Sandbox Code Playgroud)

仅将参数作为位置或关键字传递就会显着改变时间。所以我猜分区更快的另一个原因是,因为它不需要第二个参数......