Изменить: перемещение частей относительно неизменяемости в историю.
В принципе, это вопрос предварительного распределения. Когда вы используете инструкцию типа
sum(["a", "b", "c", ..., ])
и ожидаете, что она будет работать аналогично оператору reduce
, генерируемый код выглядит примерно как
v1 = "" + "a" # must allocate v1 and set its size to len("") + len("a")
v2 = v1 + "b" # must allocate v2 and set its size to len("a") + len("b")
...
res = v10000 + "$" # must allocate res and set its size to len(v9999) + len("$")
. В каждом из этих шаги создают новую строку, которая может дать некоторые накладные расходы на копирование, поскольку строки становятся длиннее и длиннее. Но, может быть, и не здесь. Более важно то, что каждая новая строка в каждой строке должна быть выделена для определенного размера (что. Я не знаю, что она должна выделяться на каждой итерации оператора reduce
, там может быть некоторые очевидные эвристики для использования, и Python может выделить немного больше здесь и там для повторного использования, но в нескольких точках новая строка будет достаточно большой, чтобы это больше не помогло, и Python должен снова выделить, что довольно дорого.
Специальный метод, подобный join
, однако имеет задачу выяснить реальный размер строки перед ее запуском и поэтому теоретически будет выделять только один раз в начале, а затем просто заполнить эту новую строку, которая намного дешевле другого решения.