
Многие почему то считают Python «медленным» языком — и часто сами делают код ещё медленнее, не зная тонкостей. При этом правильно написанный Python может быть в разы быстрее «грязного», даже без Cython или Numba.
В этой статье — 12 проверенных приёмов, которые реально ускоряют код:
- от выбора структур данных,
- до профилирования и кэширования.
Все примеры — с замерами времени, пояснениями и готовым кодом.
Оглавление
1. Используйте set вместо list для проверки вхождения
Проблема
items = list(range(10000))
if 9999 in items: # O(n) — линейный поиск
...
Это очень медленно при больших списках.
Решение
items = set(range(10000))
if 9999 in items: # O(1) — мгновенно
...
💡
setиспользует хеш-таблицу — проверка принадлежности — константная.
2. Собирайте строки через str.join(), а не +=
Медленный способ
result = ""
for word in words:
result += word + " " # создаёт новый объект каждый раз
Быстрый способ
result = " ".join(words) # один вызов, минимум аллокаций
📊 На 10 000 строк разница — в 100 раз.
3. List comprehensions быстрее циклов for
Сравнение
# Медленно
squares = []
for x in range(1000):
squares.append(x**2)
# Быстро
squares = [x**2 for x in range(1000)]
List comprehension компилируется в более эффективный байт-код. Подробнее о list comprehensions и других python фишках — в статье редкие трюки python.
4. Используйте collections.Counter вместо ручного подсчёта
Плохо
counts = {}
for item in items:
counts[item] = counts.get(item, 0) + 1
Хорошо
from collections import Counter
counts = Counter(items)
И быстрее, и читабельнее.
📚 Документация: collections.Counter
5. Кэшируйте дорогие вызовы через @lru_cache
from functools import lru_cache
@lru_cache(maxsize=128)
def expensive_function(n):
return fib(n) # рекурсивный подсчёт
print(expensive_function(40)) # повторный вызов — мгновенно
💡 Идеально для рекурсии, API-запросов, сложных вычислений.
Кэширование особенно полезно в скриптах, которые запускаются регулярно — например, в автоматическом резервном копировании файлов, где повторные вызовы одних и тех же функций неизбежны.
6. Профилируйте код — не гадайте
Не оптимизируйте наугад. Используйте встроенный профилировщик:
import cProfile
def main():
# ваш код
pass
cProfile.run('main()', sort='cumtime')
Он покажет, какие функции тратят больше всего времени.
7. Избегайте повторных вычислений в цикле
Ошибка
for i in range(len(data)):
process(data[i], config.get("param")) # вызывается на каждой итерации
Исправление
param = config.get("param")
for item in data:
process(item, param)
8. Выбирайте правильные структуры данных
- Нужно быстро добавлять в конец и удалять с начала? →
collections.deque - Нужен очередь по приоритету? →
heapq - Нужны именованные поля? →
dataclassилиnamedtuple
Пример:
from collections import deque
q = deque()
q.appendleft(1) # O(1)
q.pop() # O(1)
9. Не копируйте данные без необходимости
Используйте срезы, генераторы, itertools:
# Вместо
big_list[:] = [x for x in big_list if x > 0]
# Лучше — фильтр «на лету»
filtered = (x for x in big_list if x > 0)
Генераторы экономят память и время.
10. Используйте f-строки вместо .format() и %
name = "Иван"
# Быстро
msg = f"Привет, {name}!"
# Медленно
msg = "Привет, {}!".format(name)
F-строки компилируются на этапе парсинга — это самый быстрый способ.
11. Избегайте глубокой вложенности в циклах
Если внутри цикла — ещё цикл — и ещё один — код не только медленный, но и не читаемый. Выносите логику в функции:
for user in users:
if is_active(user):
send_report(user) # внутри — своя проверка данных
12. Замеряйте — не верьте на слово
Используйте timeit для точных замеров:
import timeit
time1 = timeit.timeit(lambda: " ".join(words), number=10000)
time2 = timeit.timeit(lambda: slow_concat(words), number=10000)
print(f"join быстрее в {time2/time1:.1f} раз")
Заключение
Ускорение Python — это не про магию, а про осознанный выбор:
- Правильные структуры данных
- Минимизация операций
- Кэширование и профилирование
Эти 12 приёмов работают сегодня, без установки новых библиотек, и особенно полезны, когда вы пишете автоматизированные скрипты — будь то парсинг, бэкапы или уведомления. Чтобы глубже освоить эти навыки, изучите рубрику Советы и Python-трюки.
🐍 Помните: лучшая оптимизация — не делать лишнего.
• чистый код python — как писать понятные и поддерживаемые скрипты
• редкие трюки python — малоизвестные, но мощные фичи языка
📢 Подписывайтесь на Telegram-канал PythonAuto, чтобы не пропустить новые гайды по автоматизации, парсингу и Python.
👉 Ваш интерес — лучшая мотивация для новых статей!