Chr*_*ier 34 python performance python-internals
我想知道为什么repr(int)比快str(int).使用以下代码段:
ROUNDS = 10000
def concat_strings_str():
return ''.join(map(str, range(ROUNDS)))
def concat_strings_repr():
return ''.join(map(repr, range(ROUNDS)))
%timeit concat_strings_str()
%timeit concat_strings_repr()
Run Code Online (Sandbox Code Playgroud)
我得到了这些时间(python 3.5.2,但与2.7.12的结果非常相似):
1.9 ms ± 17.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
1.38 ms ± 9.07 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Run Code Online (Sandbox Code Playgroud)
如果我走在正确的道路上,同样的功能long_to_decimal_string就会在引擎盖下面调用.
我错了什么或者我还缺少什么?
更新:这可能没有什么用int的__repr__或__str__方法,但之间的差异repr()和str(),如int.__str__和int.__repr__实际上相当快:
def concat_strings_str():
return ''.join([one.__str__() for one in range(ROUNDS)])
def concat_strings_repr():
return ''.join([one.__repr__() for one in range(ROUNDS)])
%timeit concat_strings_str()
%timeit concat_strings_repr()
Run Code Online (Sandbox Code Playgroud)
结果是:
2.02 ms ± 24.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.05 ms ± 7.07 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Run Code Online (Sandbox Code Playgroud)
Jim*_*ard 33
因为str(obj)必须首先通过type.__call__然后str.__new__(创建一个新的字符串)然后PyObject_Str(从对象中创建一个字符串)调用int.__str__,最后使用你链接的函数.
repr(obj),对应于builtin_repr,直接调用PyObject_Repr(获取对象repr)然后调用int.__repr__它使用相同的函数int.__str__.
此外,它们所采用的路径call_function(处理为调用生成的CALL_FUNCTION操作码的函数)略有不同.
来自GitHub上的主分支(CPython 3.7):
str经历_PyObject_FastCallKeywords(这是调用的那个type.__call__).除了执行更多检查之外,还需要创建一个元组来保存位置参数(请参阅参考资料_PyStack_AsTuple).repr通过_PyCFunction_FastCallKeywords哪些电话_PyMethodDef_RawFastCallKeywords.repr也很幸运,因为它只接受一个参数(开关引导它进入METH_0案例_PyMethodDef_RawFastCallKeywords),不需要创建元组,只需索引args.正如你的更新所述,这不是关于int.__repr__vs int.__str__,它们毕竟是相同的功能; 它是关于如何repr和str达到它们的全部.str只需要更努力地工作.
有几种可能性,因为负责str和repr返回的CPython函数略有不同.
但我想主要的原因是,str是type(A类)和str.__new__方法调用__str__,同时repr可以直接去__repr__.
| 归档时间: |
|
| 查看次数: |
2397 次 |
| 最近记录: |