Эти два решения делают очень разные вещи. Первые циклы вложены , затем вычисляются индексы с list.index
, что фактически делает этот цикл с двойным вложением и требует 125 000 000 операций. Вторая итерация выполняется на шаге, делая 500 пар без выполнения 250000 операций. Не удивительно, что они такие разные!
Вы знакомы с Big O нотацией для описания сложности алгоритмов? Если это так, первое решение - кубический , а второе решение - линейный . Стоимость выбора первого вместо второго будет расти с пугающей скоростью, так как a
и b
становятся длиннее, поэтому никто не будет использовать такой алгоритм.
Лично я почти наверняка использовал бы код вроде
', '.join('%s=%s' % pair for pair in itertools.izip(a, b))
или если бы меня не слишком волновали размеры a
и b
и просто быстрая запись, я бы использовал zip
вместо itertools.izip
. Этот код имеет несколько преимуществ
Это линейно. Хотя преждевременная оптимизация является огромной проблемой, лучше не использовать алгоритм с неоправданно плохой асимптотикой.
Это просто и идиоматично. Я вижу, как другие люди часто пишут такой код.
Это эффективная память. Используя выражение генератора вместо понимания списка (и itertools.izip
вместо zip
), я не строю ненужные списки в памяти и не превращаю то, что может быть операцией памяти O (n) (линейной) в O (1) (постоянная) операция памяти.
Что касается хронометража , чтобы найти самое быстрое решение, то это почти наверняка будет примером преждевременной оптимизации. Для написания эффективных программ мы используем теорию и опыт для написания качественного, удобного в обслуживании и хорошего кода Опыт показывает, что в лучшем случае бесполезно, а в худшем - контрпродуктивно останавливаться на случайных операциях и задавать вопрос: «Каков наилучший способ выполнить эту конкретную операцию» и пытаться определить ее по предположению или даже тестированию.
На самом деле программы с наилучшей производительностью написаны с использованием кода самого высокого качества и очень выборочной оптимизации. Высококачественный код, который оценивает удобочитаемость и простоту по сравнению с микробенчмарками, становится проще для тестирования, меньше ошибок и приятнее для рефакторинга - эти факторы являются ключевыми для эффективной оптимизации вашей программы. Время, потраченное на исправление ненужных ошибок, понимание сложного кода и борьбу с рефакторингом, можно потратить на оптимизацию.
Когда приходит время оптимизировать программу - после того, как она протестирована и, вероятно, задокументирована, - это делается не на случайных фрагментах, а на тех, которые определены в реальных случаях использования и / или тестах производительности, с измерениями, собранными с помощью профилирования . Если конкретный фрагмент кода занимает всего 0,1% времени в программе, никакое ускорение этого фрагмента не принесет никакой пользы.