Эта глава проект является частью моей предстоящей книги «От одного до нуля» (Ностарх 2021). Вы узнаете о концепции преждевременной оптимизации, и почему это вредит вашу производительность программирования. Преждевременная оптимизация является одной из основных проблем плохо написанного кода. Но что это в любом случае?
Определение преждевременной оптимизации
Определение : Преждевременная оптимизация – это акт расходов ценных ресурсов, таких как время, усилия, линии кода или даже простота – на ненужных оптимизациях кода.
Нет ничего плохого в оптимизированном коде.
Проблема в том, что нет такой вещи, как бесплатный обед. Если вы считаете, что вы оптимизируете фрагменты кода, то, что вы действительно делаете, это торговать одну переменную (например, сложность) против другой переменной (например, производительность).
Иногда вы можете получить чистый код, который также является более исполком и проще для чтения – но вы должны провести время, чтобы добраться до этого состояния! В других случаях вы преждевременно тратите больше линий кода в современном алгоритме для улучшения скорости выполнения. Например, вы можете добавить 30% больше строк кода для повышения скорости выполнения на 0,1%. Эти типы компромиссов будут зависать весь процесс разработки программного обеспечения, когда он выполняется неоднократно.
Дональд Кнут Цитата преждевременной оптимизации
Но не берите мое слово для этого. Вот что один из самых
«Программисты отслеживают огромное количество времени, думая о том, или беспокоится о скорости некритических частей их программ, и эти попытки на самом деле оказывают сильное негативное воздействие при рассмотрении отладки и технического обслуживания. Мы должны забыть о небольших проявлениях, говорите о 97% времени: преждевременная оптимизация является корнем всего зла ». – Дональд Кнут
Кнута утверждает, что большую часть времени вы не должны беспокоить ваш код, чтобы получить небольшие повышения эффективности. Давайте погрузимся в пять практических экземпляров преждевременной оптимизации, чтобы увидеть, как она может получить вас.
Шесть примеров преждевременной оптимизации
Существует много ситуаций, когда может возникнуть преждевременная оптимизация. Следите за тем! Далее я покажу вам шесть случаев, но я уверен, что есть больше.
Преждевременное оптимизация кодовых функций
Во-первых, вы проводите много времени, оптимизирующую функцию кода или фрагмент кода, которые вы просто не можете стоять оставляя неоптимизированным. Вы утверждаете, что это плохое стиль программирования для использования наивного метода, и вы должны использовать более эффективные структуры данных или алгоритмы для решения проблемы. Итак, вы погрузитесь в режим обучения, и вы найдете лучшие и лучшие алгоритмы. Наконец, вы решите о том, что считается лучшее – но это займет у вас часы и часы, чтобы заставить их работать. Оптимизация была преждевременной, потому что, как получается, ваш фрагмент кода выполнен только редко, и он не приводит к значимым улучшениям производительности.
Преждевременная оптимизация функций программного продукта
Во-вторых, вы добавляете больше функций для вашего программного продукта, потому что вы считаете, что пользователи понадобятся им. Вы оптимизируете для ожидаемого, но потребности недоказанных пользователей. Скажите, что вы разработаете приложение для смартфона, которое переводит текст в световые света MORSE. Вместо того, чтобы разработать минимальный жизнеспособный продукт (MVP, см. Главу 3), что делает только что, вы добавляете все больше и больше функций, которые вы ожидаете, необходимы, например, текст для преобразования звука и даже приемника, который переводит светлые сигналы в текст. Позже вы узнаете, что ваши пользователи никогда не используют эти функции. Преждевременная оптимизация значительно снизила ваш цикл разработки продукта и снижает вашу скорость обучения.
Преждевременная оптимизация фазы планирования
В-третьих, вы преждевременно оптимизируете фазу планирования, пытаясь найти решения всем видам проблем, которые могут возникнуть. Хотя очень дорого избежать планирования, многие люди никогда не прекращают планировать, что может быть так же дорого! Только сейчас затраты – это возможность не принимать меры. Создание программного продукта реальность требует, чтобы вы отправили что-то ценное значение для реального мира – даже если эта вещь не идеальна. Вам нужны отзывы пользователя и проверка реальности, прежде чем даже знать, какие проблемы будут ударить вас самым сложным. Планирование может помочь вам избежать много подводных камней, но если вы тип человека без уклон в направлении действий, все ваше планирование превратится в ничего по ценности.
Преждевременная оптимизация масштабируемости
В-четвертых, вы преждевременно оптимизируете масштабируемость вашего приложения. Ожидая миллионы посетителей, вы проектируете распределенную архитектуру, которая динамически добавляет виртуальные машины для обработки пиковой нагрузки при необходимости. Распределенные системы являются сложными и подверженными ошибкам, и требуется у вас месяцы, чтобы сделать вашу систему. Еще хуже, я видел больше случаев, когда распределение уменьшило масштабируемость приложения из-за повышенного накладных расходов для согласованности связи и данных. Масштабируемые распределенные системы всегда приходят по цене – вы уверены, что вам нужно заплатить? Какой смысл быть в состоянии масштабировать до миллионов пользователей, если вы даже не служили первым?
Преждевременная оптимизация тестового дизайна
В-пятых, вы верите в развитие, ориентированные на тестовые, и вы настаиваете на 100% тестовом покрытии. Некоторые функции не одают отдачи от единичных тестов из-за их нетерминированного входа (например, функции, которые обрабатывают бесплатный текст от пользователей). Несмотря на то, что у него мало ценности, вы преждевременно оптимизируете для идеального покрытия модульных испытаний, и он замедляет цикл разработки программного обеспечения при внедрении ненужной сложности в проект.
Преждевременная оптимизация объектно-ориентированного мирового здания
Шестая, вы верите в ориентацию объектов и настаивали на моделировании мира, используя сложную иерархию классов. Например, вы пишете небольшую компьютерную игру о автомобильных гонках. Вы создаете классовую иерархию, где класс Porsche наследует от класса автомобилей, который наследует от класса автомобиля. Во многих случаях эти типы сложенных структур наследования добавляют ненужную сложность и можно избежать. Вы преждевременно оптимизировали свой код, чтобы моделировать мир с более подробно, чем потребности приложений.
Код примера преждевременной оптимизации
Давайте рассмотрим небольшое приложение Python, которое должно служить примером для случая, когда преждевременной оптимизации стала плохо. Скажем, три коллеги Алисы, Боб и Карл регулярно играют в покерные игры по вечерам. Они должны отслеживать во время игры, которая обязана кому. Поскольку Алиса является страстным программистом, она решает создать небольшое приложение, которое отслеживает остатки ряда игроков.
Она подходит к коду, которое хорошо служит цели.
transactions = [] balances = {} def transfer(sender, receiver, amount): transactions.append((sender, receiver, amount)) if not sender in balances: balances[sender] = 0 if not receiver in balances: balances[receiver] = 0 balances[sender] -= amount balances[receiver] += amount def get_balance(user): return balances[user] def max_transaction(): return max(transactions, key=lambda x:x[2]) transfer('Alice', 'Bob', 2000) transfer('Bob', 'Carl', 4000) transfer('Alice', 'Carl', 2000) print('Balance Alice: ' + str(get_balance('Alice'))) print('Balance Bob: ' + str(get_balance('Bob'))) print('Balance Carl: ' + str(get_balance('Carl'))) print('Max Transaction: ' + str(max_transaction())) transfer('Alice', 'Bob', 1000) transfer('Carl', 'Alice', 8000) print('Balance Alice: ' + str(get_balance('Alice'))) print('Balance Bob: ' + str(get_balance('Bob'))) print('Balance Carl: ' + str(get_balance('Carl'))) print('Max Transaction: ' + str(max_transaction()))
Листинг: простой скрипт для отслеживания транзакций и остатков.
Сценарий имеет две глобальные переменные транзакции
и Баланс
Отказ Список транзакции
Отслеживает транзакции, как они произошли во время игры. Каждый транзакция
это кортеж идентификатора отправителя, идентификатора приемника и сумма для передачи от отправителя на приемник. Словарь Баланс
Отслеживает отображение от идентификатора пользователя к количеству кредитов, основанных на произошедших транзакциях.
Функция Передача (отправитель, приемник, сумма)
Создает и хранит новую транзакцию в глобальном списке, создает новые балансы для отправителей пользователей и приемника, если они еще не были созданы, и обновляет остатки в соответствии с транзакцией. Функция get_balance (пользователь)
Возвращает баланс пользователя, данного в качестве аргумента. Функция max_transaction ()
Переходит через все транзакции и возвращает тот, который имеет максимальное значение в третьем элементе кортежа – сумма транзакции.
Приложение Works – это возвращает следующий выход:
Balance Alice: -4000 Balance Bob: -2000 Balance Carl: 6000 Max Transaction: ('Bob', 'Carl', 4000) Balance Alice: 3000 Balance Bob: -1000 Balance Carl: -2000 Max Transaction: ('Carl', 'Alice', 8000)
Но Алиса не довольна приложением. Она понимает, что звонит max_transaction ()
Приводит к некоторым неэффективности из-за избыточных расчетов – скрипт проходит через транзакции списка дважды, чтобы найти транзакцию с максимальной суммой. Второй раз, он мог теоретически повторно использовать результат первого звонка и только взглянуть на новые транзакции.
Чтобы сделать код более эффективным, она добавляет другую глобальную переменную max_transaction
который отслеживает максимальную сумму транзакции, когда-либо видела.
transactions = [] balances = {} max_transaction = ('X', 'Y', -9999999) def transfer(sender, receiver, amount): … if amount > max_transaction[2]: max_transaction = (sender, receiver, amount)
Добавив больше сложности к коду, теперь сейчас больше исполняется – но при каких затратах? Дополнительная сложность приводит к нему значимой производительности для небольших приложений, для которых Алиса использует код. Это делает его более сложным и уменьшает ремонтопригодность. Никто никогда не узнает, что выгода производительности в вечерних игровых сессиях. Но прогресс Алисы замедляется, поскольку добавляет все больше и более глобальных переменных (например, отслеживание минимальных сумм транзакции и т. Д.). Оптимизация явно была преждевременной оптимизацией без необходимости для конкретного применения.
Вы хотите развивать навыки Хорошо округлый Python Professional То же оплачивается в процессе? Станьте питоном фрилансером и закажите свою книгу Оставляя крысиную гонку с Python На Amazon ( Kindle/Print )!
Куда пойти отсюда?
Достаточно теории, давайте познакомимся!
Чтобы стать успешным в кодировке, вам нужно выйти туда и решать реальные проблемы для реальных людей. Вот как вы можете легко стать шестифункциональным тренером. И вот как вы польские навыки, которые вам действительно нужны на практике. В конце концов, что такое использование теории обучения, что никто никогда не нуждается?
Практические проекты – это то, как вы обостряете вашу пилу в кодировке!
Вы хотите стать мастером кода, сосредоточившись на практических кодовых проектах, которые фактически зарабатывают вам деньги и решают проблемы для людей?
Затем станьте питоном независимым разработчиком! Это лучший способ приближения к задаче улучшения ваших навыков Python – даже если вы являетесь полным новичком.
Присоединяйтесь к моему бесплатным вебинаре «Как создать свой навык высокого дохода Python» и посмотреть, как я вырос на моем кодированном бизнесе в Интернете и как вы можете, слишком от комфорта вашего собственного дома.
Присоединяйтесь к свободному вебинару сейчас!
Работая в качестве исследователя в распределенных системах, доктор Кристиан Майер нашел свою любовь к учению студентов компьютерных наук.
Чтобы помочь студентам достичь более высоких уровней успеха Python, он основал сайт программирования образования Finxter.com Отказ Он автор популярной книги программирования Python One-listers (Nostarch 2020), Coauthor of Кофе-брейк Python Серия самооставленных книг, энтузиаста компьютерных наук, Фрилансера и владелец одного из лучших 10 крупнейших Питон блоги по всему миру.
Его страсти пишут, чтение и кодирование. Но его величайшая страсть состоит в том, чтобы служить стремлению кодер через Finxter и помогать им повысить свои навыки. Вы можете присоединиться к его бесплатной академии электронной почты здесь.