Python — язык программирования, известный своей простотой и читабельностью, но когда доходит до скорости — он проигрывает всем. Что очень критично, когда работаешь в машинном обучении и имеешь дело с огромным количеством данных. Сегодня рассмотрим парочку примеров, как можно ускорить ваш код на ровном месте
Использование генераторов вместо списков 🏄
Начнем с оптимизации по памяти. Представим, что перед нами стоит задача пройтись по всем данным и видоизменить их. Причем использовать векторизованные вычисления запрещено (Numpy, Pandas и др.). В этом случае первое что приходит в голову: создать список и все туда накидать. Давайте проверим сколько это займет памяти:
Для этого напишем простенькую функцию для отображения сколько занимает объект оперативки и тут же сгенерируем данных:
Скрытый текст
from sys import getsizeof from random import random def memory_consumption(obj): return f"Total MBs size: {getsizeof(obj) / 1024 ** 2}" data = [random() for _ in range(10 ** 6)]
После подгрузки данные занимают: Total MBs size: 8.057334899902344
Теперь создаем две функции:
# Первая функция через список def squares_list(data): result = [] for elem in data: result.append(elem * 2) return result # Вторая функция через генератор def squares_generator(data): for elem in data: yield elem * 2 # Пример использования squares_list(1_000_000) # Занимает много памяти squares_generator(1_000_000) # Экономит память
Тут вторая функция ничего не создает а просто возвращает вам итератор, по которому можно пробежаться и сохранить то, что вам необходимо.
✅Итоговые замеры: решение в «лоб» занимает столько же, сколько исходные данные — 8.06 MBs
, а генераторы обогнали — 1e-6 MBs
! Второе решение удобно применять там, где вам важно много раз создавать объекты либо же хранить только часть вывода
Локальные переменные 📍
Когда пишете свои pipeline, стоит учитывать, что обращение к глобальным переменным может затормозить ваш код. Избавляемся от этого немедленно!
Если это возможно не используйте оператор global
. Лучше создать новую переменную и ее сохранить в каком-либо виде
global_variable = 10 def func1(): global gloval_variable global_variable = 52 print(global_variable) def func2(): local_variable = 10 print(local_variable) func1() # Доступ к глобальной переменной func2() # Доступ к локальной переменной
Использование for вместо while ⚡️
Циклы for
в Python часто быстрее, чем циклы while
, потому что они оптимизированы для итерации по последовательностям. Если вы знаете количество итераций, используйте for
вместо while
.
# Цикл `while` i = 0 while i < 10: print(i) i += 1 # Цикл `for` for i in range(10): print(i)
Избегайте append в циклах 🌀
Использование append
внутри цикла может замедлить выполнение функции, потому что Python каждый раз создает новый список. Если возможно, используйте list
сразу с нужным размером, чтобы избежать частых перераспределений памяти.
# Использование `append` result = [] for i in range(10): result.append(i) # Создание списка с нужным размером result = [0] * 10 for i in range(10): result[i] = i
Использование map и filter 🤿
Эти функции позволяют применить функцию к каждому элементу итерируемого объекта (например, списка), не прибегая к написанию собственного цикла. Это делает код более понятным и иногда ускоряет его выполнение.
# Использование `map` numbers = [1, 2, 3, 4] squares = map(lambda x: x ** 2, numbers) print(list(squares)) # Вывод: [1, 4, 9, 16] # Использование `filter` numbers = [1, 2, 3, 4, 5] even_numbers = filter(lambda x: x % 2 == 0, numbers) print(list(even_numbers)) # Вывод: [2, 4]
Итог 🏖
Эти 5 способов оптимизации функций в Python помогут вам сделать ваш код быстрее и эффективнее. Важно помнить, что не всегда нужно использовать все эти методы одновременно. Экспериментируйте и выбирайте подходящие решения в зависимости от конкретной задачи.
Бонусом забирайте mock-собеседование, где я рассказал что еще можно встретить на собеседование на позицию Data Science. Больше про эффективную оптимизацию кода для рабочих задач я написал тут — пользуйся!
ссылка на оригинал статьи https://habr.com/ru/articles/836644/
Добавить комментарий