Написать пост

Как быстро конкатенировать строки в Python

Аватар Пётр Соковых

Обложка поста Как быстро конкатенировать строки в Python

Рассказывает Рювен Лэрнер, преподаватель

Как вы, наверное, знаете один из принципов в Python: “Должен быть один и только один способ сделать что-либо”. Можете убедиться в этом, выполнив в в интерпретаторе import this (вы увидите Дзен Python). Несмотря на это, иногда вам всё равно приходится выбирать между несколькими способами сделать что-то, и не всегда очевидно, какой способ лучше. Недавно один студент спросил меня, какой способ конкатенации строк в Python самый эффективный. Я решил поделиться результатом своего маленького исследования и с вами.

Для начала вспомним, какие способы объединения строк предоставляет нам Python. Во-первых, это оператор +:

			>> 'abc' + 'def'
'abcdef'
		

Также мы можем использовать оператор %, который, конечно, может использоваться не только для соединения строк, но и для этого тоже:

			>>> "%s%s" % ('abc', 'def')
'abcdef'
		

Есть и ещё более современная замена % — это str.format:

			>>> '{0}{1}'.format('abc', 'def')
'abcdef'
		

Так же, как и %, этот метод гораздо мощнее, чем обычный +, но тем не менее строки соединяют и с его помощью.

Как же мы будем замерять время? В Jupyter (так же известном, как IPython) мы можем использовать магическую команду timeit для запуска кода. Для запуска я подготовил четыре функции, каждая из которых складывает строки разным образом. Исходные строки хранятся в глобальных переменных (x и y), а локальная (для каждой функции) переменная z содержит результат сложения. Затем функция возвращает результат.

			def concat1(): 
    z = x + y 
    return z 

 def concat2(): 
    z = "%s%s" % (x, y) 
    return z 

def concat3(): 
    z = "{}{}".format(x, y) 
    return z 

def concat4(): 
    z = "{0}{1}".format(x, y) 
    return z
		

Конечно concat3() и concat4() фактически одинаковы, но я решил проверить и то, влияет указание порядка строк на скорость или нет. Затем я определил наши глобальные переменные:

			x = 'abc' 
y = 'def'
		

И запустил наши функции:

			%timeit concat1()
%timeit concat2()
%timeit concat3()
%timeit concat4()
		

Результат оказался следующим:

  • concat1: 153 наносекунды;
  • concat2: 275 наносекунд;
  • concat3: 398 наносекунд;
  • concat4: 393 наносекунды.

Здесь мы можем видеть, что concat1(), который использует оператор +, выполняется гораздо быстрее остальных. Это немного расстроило меня, потому что мне очень нравится str.format, однако теперь в задачах, которые требуют огромного количества обработки строк, от него придётся отказаться.

Возможно, такие результаты могут быть связаны с тем, что короткие строки не создаются в Python каждый раз снова, а хранятся в специальной таблице? Давайте попробуем изменить наши глобальные переменные следующим образом:

			x = 'abc' * 10000 
y = 'def' * 10000
		

Теперь мы получим следующие результаты:

  • concat1: 2.64 микросекунды;
  • concat2: 3.09 микросекунды;
  • concat3: 3.33 микросекунды;
  • concat4: 3.48 микросекунды;

Да, каждый из методов теперь работал гораздо дольше, однако общий результат не изменился — оператор + по прежнему лидирует. Заметим так же, что разница во времени между третьим и четвёртым методом, как и ожидалось, пренебрежимо мала.

После этого я попробовал не объявлять переменные глобальными, а задавать их в теле метода, но на результаты это всё равно не повлияло. Разумеется, можно проводить ещё много разных опытов (например, попробовать сложить больше, чем две строки), однако этого уже достаточно, чтобы иметь примерное представление о скоростях работы различных способов сложения строк в языке Python.

Следите за новыми постами
Следите за новыми постами по любимым темам
67К открытий67К показов