В Python меня ускользает от того, где и когда использовать конкатенацию строк вместо подстановки строк. Поскольку конкатенация строк значительно повысила производительность, является ли это (становится все более) стилистическим решением, а не практическим?
В качестве конкретного примера, как следует обрабатывать создание гибких URI:
DOMAIN = 'http://stackoverflow.com'
QUESTIONS = '/questions'
def so_question_uri_sub(q_num):
return "%s%s/%d" % (DOMAIN, QUESTIONS, q_num)
def so_question_uri_cat(q_num):
return DOMAIN + QUESTIONS + '/' + str(q_num)
Изменить: также были предложения о присоединении к списку строк и использовании именованной замены. Это варианты по центральной теме, а именно: как правильно это делать и в какое время? Спасибо за ответы!
python
string
string-concatenation
gotgenes
источник
источник
Ответы:
Согласно моей машине, конкатенация (значительно) быстрее. Но стилистически я готов заплатить цену замены, если производительность не критична. Ну, а если мне нужно форматирование, не нужно даже задавать вопрос ... нет другого выхода, кроме как использовать интерполяцию / шаблон.
источник
Не забываем про именованную замену:
источник
Остерегайтесь объединения строк в цикл! Стоимость конкатенации строк пропорциональна длине результата. Зацикливание приведет вас прямо в страну N-квадрата. Некоторые языки оптимизируют конкатенацию с последней выделенной строкой, но опасно рассчитывать на то, что компилятор оптимизирует ваш квадратичный алгоритм до линейного. Лучше всего использовать примитив (
join
?), Который принимает весь список строк, выполняет одно распределение и объединяет их все за один раз.источник
«Поскольку конкатенация строк значительно повысила производительность ...»
Если производительность имеет значение, это полезно знать.
Однако проблемы с производительностью, которые я видел, никогда не сводились к строковым операциям. У меня обычно были проблемы с вводом-выводом, сортировкой и O ( n 2 операциями ), которые были узкими местами.
До тех пор, пока строковые операции не станут ограничителями производительности, я буду придерживаться очевидных вещей. В основном это подстановка, когда это одна строка или меньше, конкатенация, когда это имеет смысл, и инструмент шаблона (например, Mako), когда он большой.
источник
Что вы хотите объединить / интерполировать и как вы хотите отформатировать результат, должно определять ваше решение.
Интерполяция строк позволяет легко добавлять форматирование. Фактически, ваша версия с интерполяцией строк не делает то же самое, что и версия с конкатенацией; он фактически добавляет перед
q_num
параметром дополнительную косую черту . Чтобы сделать то же самое, вам нужно будет написатьreturn DOMAIN + QUESTIONS + "/" + str(q_num)
в этом примере.Интерполяция упрощает форматирование чисел;
"%d of %d (%2.2f%%)" % (current, total, total/current)
будет гораздо менее читаемым в форме конкатенации.Конкатенация полезна, когда у вас нет фиксированного количества элементов для преобразования в строку.
Также знайте, что Python 2.6 представляет новую версию строковой интерполяции, которая называется строковым шаблоном :
Планируется, что шаблонирование строк в конечном итоге заменит% -интерполяцию, но я думаю, что это произойдет не скоро.
источник
Я просто из любопытства тестировал скорость различных методов конкатенации / подстановки строк. Поиск в Google по этой теме привел меня сюда. Я думал, что опубликую результаты своих тестов в надежде, что они помогут кому-нибудь принять решение.
... После запуска
runtests((percent_, format_, format2_, concat_), runs=5)
я обнаружил, что метод% примерно в два раза быстрее других на этих маленьких строках. Метод concat всегда был самым медленным (едва ли). Были очень крошечные различия при переключении позиций вformat()
методе , но переключение позиций всегда было как минимум на 0,01 медленнее, чем метод обычного формата.Пример результатов тестирования:
Я запустил их, потому что я использую конкатенацию строк в своих скриптах, и мне было интересно, сколько это стоит. Я запускал их в разном порядке, чтобы убедиться, что ничто не мешает и не улучшает производительность в первую или в последнюю очередь. На стороне записки, я бросил в некоторых длинных строковых генераторах в эти функции , как
"%s" + ("a" * 1024)
и регулярный CONCAT был почти в 3 раза быстрее (1,1 против 2,8) , как с использованиемformat
и%
методов. Думаю, это зависит от струн и от того, чего вы пытаетесь достичь. Если производительность действительно имеет значение, возможно, лучше попробовать разные вещи и протестировать их. Я предпочитаю удобочитаемость скорости, если только скорость не становится проблемой, но это только я. ТАК не понравилась моя копия / вставка, мне пришлось поставить 8 пробелов, чтобы все выглядело правильно. Я обычно использую 4.источник
str.format()
иstr.join()
более обычную конкатенацию. Я также слежу за «f-strings» из PEP 498 , который недавно был принят. Что касаетсяstr()
вызовов, влияющих на производительность, я уверен, что вы правы. Я понятия не имел, насколько дорогими были вызовы функций в то время. Я по-прежнему считаю, что тесты нужно проводить, когда есть сомнения.join_(): return ''.join(["test ", str(1), ", with number ", str(2)])
, кажетсяjoin
, тоже медленнее, чем в процентах.Помните, что стилистические решения - это практические решения, если вы когда-нибудь планируете поддерживать или отлаживать свой код :-) Есть известная цитата Кнута (возможно, цитирующего Хора?): «Мы должны забыть о небольшой эффективности, скажем, примерно в 97% случаев: преждевременная оптимизация - корень всех зол ».
Пока вы будете осторожны, чтобы (сказать) не превратить задачу O (n) в задачу O (n 2 ), я бы выбрал то, что вам будет легче понять.
источник
Я использую замену везде, где могу. Я использую конкатенацию только в том случае, если я создаю строку, например, в цикле for.
источник
На самом деле, правильнее всего в этом случае (строительные пути) использовать
os.path.join
. Не конкатенация или интерполяция строкисточник