Есть ли эффективный массовый метод конкатенации строк в Python (например, StringBuilder в C # или StringBuffer в Java)? Я нашел следующие методы здесь :
- Простое объединение с использованием
+
- Использование списка строк и
join
метода - Использование
UserString
изMutableString
модуля - Использование массива символов и
array
модуля - Использование
cStringIO
изStringIO
модуля
Но что вы, эксперты, используете или предлагаете и почему?
f''
строки форматирования, которые будут быстрее любых альтернатив в предыдущих версиях Python.Ответы:
Вы можете быть заинтересованы в этом: Анекдот оптимизации от Guido. Хотя стоит помнить также, что это старая статья, и она предшествует существованию таких вещей, как
''.join
(хотя я думаю,string.joinfields
что более или менее то же самое)В силу этого,
array
модуль может быть самым быстрым, если вы можете включить в него свою проблему. Но''.join
, вероятно, он достаточно быстр и имеет преимущество в том, что он идиоматичен, и поэтому его легче понять другим программистам на Python.Наконец, золотое правило оптимизации: не оптимизируйте, если вы не знаете, что нужно, и измеряйте, а не угадывайте.
Вы можете измерить различные методы, используя
timeit
модуль. Это может сказать вам, что является самым быстрым, вместо случайных незнакомцев в Интернете, делающих догадки.источник
.join()
? Основной вопрос заключается в том, создает ли это a) копию строки для конкатенации (аналогичноs = s + 'abc'
), для которой требуется время выполнения O (n), или b) просто добавляется к существующей строке, не создавая копию, для которой требуется O (1) ?''.join(sequenceofstrings)
это то, что обычно работает лучше всего - самый простой и быстрый.источник
''.join(sequence)
идиому. Особенно полезно создавать разделенные запятыми списки:', '.join([1, 2, 3])
выдает строку'1, 2, 3'
."".join(chr(x) for x in xrange(65,91))
--- в этом случае аргумент для присоединения является итератором, созданным с помощью выражения генератора. Там нет временного списка, который создается.Python 3.6 изменил игру для конкатенации строк известных компонентов с помощью Literal String Interpolation .
Учитывая тестовый пример из ответа Мкойстинена , имея строки
Претенденты
f'http://{domain}/{lang}/{path}'
- 0,151 мкс'http://%s/%s/%s' % (domain, lang, path)
- 0,321 мкс'http://' + domain + '/' + lang + '/' + path
- 0,356 мкс''.join(('http://', domain, '/', lang, '/', path))
- 0,249 мкс (обратите внимание, что построение кортежа постоянной длины немного быстрее, чем создание списка постоянной длины).Таким образом, в настоящее время самый короткий и самый красивый код также самый быстрый.
В альфа-версиях Python 3.6 реализация
f''
строк была самой медленной из возможных - фактически сгенерированный байт-код в значительной степени эквивалентен''.join()
случаю с ненужными вызовами,str.__format__
которые без аргументов просто возвращали быself
без изменений. Эти недостатки были устранены до финальной версии 3.6.Скорость можно сравнить с самым быстрым методом для Python 2, который является
+
конкатенацией на моем компьютере; и это занимает 0,203 мкс с 8-битными строками и 0,259 мкс, если все строки являются Unicode.источник
Это зависит от того, что вы делаете.
После Python 2.5 конкатенация строк с оператором + выполняется довольно быстро. Если вы просто объединяете пару значений, лучше использовать оператор +:
Однако, если вы собираете строку в цикле, вам лучше использовать метод объединения списков:
... но обратите внимание, что вы должны собрать относительно большое количество строк, прежде чем разница станет заметной.
источник
Согласно ответу Джона Фухи, не оптимизируйте без необходимости, но если вы здесь и задаете этот вопрос, это может быть именно потому, что вам нужно . В моем случае мне нужно было собрать несколько URL из строковых переменных ... быстро. Я заметил, что никто (пока), похоже, не рассматривает метод строкового формата, поэтому я подумал, что попробую это, и, в основном, из-за небольшого интереса, я решил добавить туда оператор строковой интерполяции для лучшего измерения. Честно говоря, я не думал, что ни один из них не будет преобразован в прямую операцию «+» или «.join ()». Но угадайте что? В моей системе Python 2.7.5 оператор строковой интерполяции управляет ими всеми, а string.format () работает хуже всех:
Результаты:
Если я использую более короткий домен и более короткий путь, интерполяция все еще выигрывает. Разница более выражена, однако, с более длинными строками.
Теперь, когда у меня был хороший тестовый скрипт, я также тестировал под Python 2.6, 3.3 и 3.4, вот результаты. В Python 2.6 оператор плюс - самый быстрый! На Python 3 присоединение выигрывает. Примечание: эти тесты очень повторяются в моей системе. Таким образом, «плюс» всегда быстрее в 2.6, «intp» всегда быстрее в 2.7 и «соединение» всегда быстрее в Python 3.x.
Урок выучен:
ТЛ; др:
источник
f'http://{domain}/{lang}/{path}'
.format()
есть три формы, в порядке от быстрого к медленному:"{}".format(x)
,"{0}".format(x)
,"{x}".format(x=x)
это в значительной степени зависит от относительных размеров новой строки после каждой новой конкатенации. С помощью
+
оператора для каждой конкатенации создается новая строка. Если промежуточные строки относительно долго,+
становится все более и более медленно , потому что новый посредник строка хранится.Рассмотрим этот случай:
Полученные результаты
1 0,00493192672729
2 0.000509023666382
3 0.00042200088501
4 0.000482797622681
В случае 1 и 2 мы добавляем большую строку, а join () работает примерно в 10 раз быстрее. В случаях 3 и 4 мы добавляем небольшую строку, и «+» работает немного быстрее
источник
Я столкнулся с ситуацией, когда мне нужно было добавить строку неизвестного размера. Это результаты тестов (python 2.7.3):
Это, кажется, показывает, что «+ =» является самым быстрым. Результаты по ссылке Skymind немного устарели.
(Я понимаю, что второй пример не завершен, к окончательному списку нужно будет присоединиться. Однако это показывает, что простая подготовка списка занимает больше времени, чем строка concat.)
источник
Через год давайте проверим ответ mkoistinen с помощью python 3.4.3:
Ничего не изменилось. Регистрация по-прежнему самый быстрый метод. Поскольку intp является, пожалуй, лучшим выбором с точки зрения читабельности, вы, возможно, захотите использовать intp.
источник
Вдохновленный тестами @ JasonBaker, вот простой пример, сравнивающий 10
"abcdefghijklmnopqrstuvxyz"
строк и показывающий, что.join()
он быстрее; даже с этим крошечным увеличением переменных:сцепление
Присоединиться
источник
Для небольшого набора из коротких строк (то есть 2 или 3 строк не больше , чем несколько символов), а также по - прежнему намного быстрее. Используя замечательный скрипт mkoistinen в Python 2 и 3:
Поэтому, когда ваш код выполняет огромное количество отдельных небольших объединений, плюс является предпочтительным способом, если скорость имеет решающее значение.
источник
Вероятно, «новые f-строки в Python 3.6» - наиболее эффективный способ объединения строк.
Используя% s
Использование .format
Используя f
Источник: https://realpython.com/python-f-strings/
источник