为什么repr(int)比str(int)更快?

时间:2017-07-28 15:01:12

标签: 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()

我得到了这些时间(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)

如果我走在正确的道路上,the same function long_to_decimal_string is getting called在引擎盖下方。

我错了什么或者我还缺少什么?

更新: 这可能与int的{​​{1}}或__repr__方法无关,但__str__repr()之间存在差异,str()int.__str__ {1}}事实上相对较快:

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()

3 个答案:

答案 0 :(得分:33)

因为使用str(obj)必须首先通过type.__call__然后str.__new__ (create a new string)然后调用PyObject_Str (make a string out of the object)int.__str__最终,你链接的功能。

repr(obj)对应的

builtin_repr会直接调用PyObject_Repr (get the object repr),然后调用使用与int.__str__相同功能的int.__repr__

此外,他们通过call_function(处理为调用生成的CALL_FUNCTION opcode的函数)所采用的路径略微不同。

来自GitHub上的主分支(CPython 3.7):

根据您的更新说明,这不是int.__repr__int.__str__的关系,它们毕竟是相同的功能;这完全取决于reprstr如何与他们联系。 str只需要更努力地工作。

答案 1 :(得分:12)

我刚刚比较了3.5分支中的strrepr实现。 请参阅here

strenter image description here

似乎有更多支票

答案 2 :(得分:8)

有几种可能性,因为负责strrepr返回的CPython函数略有不同。

但我想主要原因是strtype(一个类),而str.__new__方法必须调用__str__repr可以直接转到__repr__