- Продуктивність більш не важлива
- Швидкість - єдина річ, яка має значення.
- Поговоримо про мікросервісах
- Процесор не є вашим вузьким місцем
- Що, якщо ми все-таки впираємося в CPU?
- Так що, Python швидкий?
- Але що, якщо швидкість дійсно важлива?
- Дісклаймер
- оптимізуючи Python
Наша команда-партнер Artmisto
оригінал: 'Yes, Python is Slow, and I Do not Care' by Nick Humrich; переклад був вперше опублікований на Хабрахабр .
Я беру паузу в моєму обговоренні asyncio в Python, щоб поговорити про швидкість Python. Дозвольте представитися, я - затятий шанувальник Python, і використовую його всюди, де тільки вдається. Одна з причин, чому люди виступають проти цієї мови, - то, що він повільний. Деякі відмовляються навіть спробувати на ньому попрацювати лише через те, що «X швидше». Ось мої думки на цей рахунок.
Продуктивність більш не важлива
Раніше програми виконувалися дуже довго. Ресурси процесора і пам'яті були дорогими, і час роботи було важливим показником. А вже скільки платили за електрику! Однак, ті часи давно пройшли, тому що головне правило говорить:
Оптимізуйте використання своїх найдорожчих ресурсів.
Історично найдорожчим було процесорний час. Саме до цього підводять при вивчення інформатики, фокусуючись на ефективності різних алгоритмів. На жаль, це вже не так - залізо зараз дешево як ніколи, а слідом за ним і час виконання стає все дешевше. Найдорожчим же стає час співробітника, тобто вас. Набагато важливіше вирішити задачу, ніж прискорити виконання програми. Повторюся для тих, хто просто перегортає цю статтю:
Набагато важливіше вирішити задачу, ніж прискорити виконання програми.
Ви можете заперечити: «У моїй компанії піклуються про швидкість. Я створюю веб-додаток, в якому всі відповіді приходять менше, ніж за x мілісекунд »або« від нас йшли клієнти, тому що вважали наш додаток занадто повільним ». Я не кажу, що швидкість роботи не важлива зовсім, я хочу лише сказати, що вона перестала бути найважливішою; це вже не найдорожчий ваш ресурс.
Швидкість - єдина річ, яка має значення.
Коли ви вживаєте слово «швидкість» в контексті програмування, скоріше за все ви маєте на увазі продуктивність CPU. Але коли ваш CEO вживає його стосовно програмування, то він має на увазі швидкість бізнесу. Найголовніша метрика - час виходу на ринок. В кінцевому рахунку неважливо наскільки швидко працюють ваші продукти, не має значення якою мовою програмування вони написані або скільки потрібно ресурсів для їх роботи. Єдина річ, яка змусить вашу компанію вижити або вмерти, - це час виходу на ринок. Я говорю більше не про те, наскільки швидко ідея почне приносити дохід, а про те, як швидко ви зможете випустити першу версію продукту. Єдиний спосіб вижити в бізнесі - розвиватися швидше, ніж конкуренти. Неважливо, скільки у вас ідей, якщо конкуренти реалізують їх швидше. Ви повинні бути першими на ринку, ну або як мінімум не відставати. Трохи загальмувати - і загинете.
Єдиний спосіб вижити в бізнесі - розвиватися швидше, ніж конкуренти.
Поговоримо про мікросервісах
Великі компанії, такі як Amazon, Google або Netflix, розуміють важливість швидкого розвитку. Вони спеціально будують свій бізнес так, щоб швидко вводити інновації. Мікросервіси допомагають їм в цьому. Ця стаття не має ніякого відношення до того, чи слід вам будувати на них свою архітектуру, але, по крайней мере, погодитеся з тим, що Amazon і Google повинні їх використовувати. Мікросервіси повільні за своєю суттю. Сама їхня концепція полягає в тому, щоб використовувати Інтернет-дзвінки. Іншими словами, замість виклику функції ви відправляєтеся гуляти по мережі. Що може бути гірше з точки зору продуктивності ?! Інтернет-дзвінки дуже повільні в порівнянні з тактами процесора. Однак, великі компанії як і раніше вважають за краще будувати архітектуру на основі мікросервісов. Я дійсно не знаю, що може бути повільніше. Найбільший мінус такого підходу - продуктивність, в той час як плюсом буде час виходу на ринок. Створюючи команди навколо невеликих проектів і кодових баз, компанія може проводити ітерації і вводити інновації набагато швидше. Ми бачимо, що навіть дуже великі компанії піклуються про час виходу на ринок, а не тільки стартапи.
Процесор не є вашим вузьким місцем
Якщо ви пишете мережеве додаток, таке як веб-сервер, швидше за все, процесор не є вузьким місцем вашого застосування. В процесі обробки запиту буде зроблено кілька мережевих звернень, наприклад, до бази даних або кешу. Ці сервера можуть бути як завгодно швидкими, але все упреться в швидкість передачі даних по мережі. Ось дійсно класна стаття, в якій порівнюється час виконання кожної операції. У ній автор вважає за один такт процесора одну секунду. В такому випадку запит з Каліфорнії до Нью-Йорка розтягнеться на 4 роки. Ось така от мережа повільна. Для зразкових розрахунків припустимо, що передача даних по мережі всередині датацентру займає близько 3 мс, що еквівалентно 3 місяців за нашою шкалою відліку. Тепер візьмемо програму, яка навантажує CPU. Припустимо, їй треба 100 000 циклів, щоб обробити один виклик, це буде еквівалентно 1 дня. Припустимо, що ми пишемо на мові, який в 5 разів повільніше - це займе 5 днів. Для тих, хто готовий чекати 3 місяці, різниця в 4 дня вже не так важлива.
В остаточному підсумку те, що python повільний, вже не має значення. Швидкість мови (або процесорного часу) майже ніколи не є проблемою. Google описав це в своєму дослідженні . А там, між іншим, говориться про розробку високопродуктивної системи. У висновку приходять до наступного висновку:
Рішення використовувати інтерпретована мова програмування в високопродуктивних додатках може бути парадоксальним, але ми зіткнулися з тим, що CPU рідко коли є стримуючим фактором; виразність мови означає, що більшість програм невеликі і більшу частину часу витрачають на введення-виведення, а не на власний код. Більш того, гнучкість інтерпретується реалізації була корисною, як в простоті експериментів на лінгвістичному рівні, так і в наданні нам можливості досліджувати способи розподілу обчислень на багатьох машинах.
Іншими словами:
CPU рідко коли є стримуючим фактором.
Що, якщо ми все-таки впираємося в CPU?
Що щодо таких аргументів: «Все це прекрасно, але що, якщо CPU стає вузьким місцем і це починає позначатися на продуктивності?» Або «Мова x менш вимогливий до заліза, ніж y»? Вони теж мають місце бути, однак ви можете масштабувати додаток горизонтально нескінченно. Просто додайте серверів, і сервіс буде працювати швидше :) Без сумніву, Python більш вимогливий до заліза, ніж той же C, але вартість нового сервера набагато менше вартості вашого часу. Тобто дешевше буде докупити ресурсів, а не кидатися кожен раз щось оптимізувати.
Так що, Python швидкий?
Протягом всієї статті я твердив, що найважливіше - час розробника. Таким чином, залишається відкритим питання: чи швидше Python мови X під час розробки? Смішно, але я, Google і дехто ще , Можуть підтвердити наскільки продуктивний Python. Він приховує так багато речей від вас, допомагаючи зосередитися на основній вашої задачі і не відволікаючись на всякі дрібниці. Давайте розглянемо деякі приклади з життя.
Здебільшого всі суперечки навколо продуктивності Python скочуються до порівняння динамічної та статичної типізації. Думаю, всі погодяться, що статично типізовані мови менш продуктивні, але про всяк випадок ось хорошая статья , Яка пояснює чому. Що стосується безпосередньо Python, тобто хороший звіт про дослідження , В якому розглядається, скільки часу знадобилося, щоб написати код для обробки рядків на різних мовах.
У представленому вище дослідженні Python більш ніж в 2 рази продуктивніше Java. Багато інших також мови програмування дають схожий результат. Rosetta Code провів досить широке дослідження відмінностей вивчення мов програмування. У статті вони порівнюють python з іншими інтерпретуються мовами і заявляють:
Python, в цілому, найбільш короткий, навіть в порівнянні з функціональними мовами (в середньому в 1,2-1,6 рази коротше).
Мабуть, в реалізації на Python буде як правило менше рядків коду, ніж на будь-якому іншому мовою. Це може здатися жахливої метрикою, проте кілька досліджень , В тому числі і згаданих вище, показують, що час, витрачений на кожен рядок коду, приблизно однаково на кожній мові. Таким чином, чим менше рядків коду, тим більше продуктивність. Навіть сам codinghorror (програміст на C #) написав статтю про те, що Python більш продуктивний.
Я думаю, буде справедливо сказати, що Python більш продуктивний, ніж багато інших мов програмування. В основному це пов'язано з тим, що він поставляється «з батарейками», а також має безліч сторонніх бібліотек на всі випадки життя. ось невелика стаття , Що порівнює Python і X. Якщо ви мені не вірите, можете самі переконатися наскільки ця мова програмування простий і зручний. Ось ваша перша програма:
import __hello__
Але що, якщо швидкість дійсно важлива?
Мої міркування вище могли скласти думку, що оптимізація і швидкість виконання програми взагалі не мають значення. У багатьох випадках це не так. Наприклад, у вас є веб-додаток і деякий endpoint, який вже дуже гальмує. У вас можуть бути навіть певні вимоги на цей рахунок. Наш приклад будується на деяких припущеннях:
- є певний endpoint, який виконується повільно
- є деякі метрики, що визначають наскільки повільними може бути обробка запитів
Ми не будемо займатися мікро-оптимізацією всього програми. Все повинно бути «достатньо швидко». Ваші користувачі можуть помітити, якщо обробка запиту займає секунди, але вони ніколи не помітять різницю між 35 мс і 25 мс. Вам потрібно лише зробити додаток «досить хорошим».
Дісклаймер
Мушу зауважити, що є деякі програми, які обробляють дані в реальному часі, які потребують мікрооптімізаціі, і кожна мілісекунда має значення. Але це швидше виняток, ніж правило.
Щоб зрозуміти як оптимізувати, ми повинні спочатку зрозуміти що саме треба оптимізувати. В кінці кінців:
Будь-які поліпшення, зроблені де-небудь крім вузького місця, є ілюзією. - Джин Кім.
Якщо оптимізація не усуває вузького місця докладання, то ви просто витратите даремно свій час і не вирішите реальну проблему. Ви не повинні продовжувати розробку, поки не виправите гальма. Якщо ви намагаєтеся оптимізувати щось, не знаючи конкретно що, то навряд чи результат вас задовольнить. Це і називається «передчасної оптимізацією» - поліпшення продуктивності без будь-яких метрик. Д. Кнута часто приписують таку цитату, хоча він стверджує, що вона не його:
Передчасна оптимізація - корінь всіх зол.
Якщо бути точним, то більш повна цитата:
Ми повинні забути про ефективність, скажімо, на 97% часу: передчасна оптимізація - корінь всіх зол. Однак ми не повинні випустити наші можливості в цих критичних 3%.
Іншими словами, тут йдеться про те, що більшу частину часу вам не потрібно думати про оптимізацію. Код і такий хороший :) А в разі, коли це не так, потрібно переписати не більше 3% Вас ніхто не похвалить, якщо ви зробите обробку запиту на кілька наносекунд швидше. Оптимізуйте те, що піддається виміру.
Передчасна оптимізація, як правило, полягає у виклику більш швидких методів <прим пер. мабуть, маються на увазі асемблерні вставки> або використанні специфічних структур даних через їх внутрішньої реалізації. В університеті нас вчили, що якщо два алгоритму мають одну асимптотику Big-O, то вони еквівалентні. Навіть якщо один з них в 2 рази повільніше. Комп'ютери зараз настільки швидкі, що обчислювальну складність пора вимірювати на великій кількості даних. Тобто, якщо у вас є дві функції O (log n), але одна в два рази повільніше інший, то це не має великого значення. У міру збільшення розміру даних вони обидві починають показувати приблизно одне й те саме час виконання. Ось чому передчасна оптимізація - це корінь усього зла; Це витрачає наш час і практично ніколи не допомагає нашим спільним продуктивності.
У термінах Big-O всі мови програмування мають складність O (n), де n - кількість рядків коду або інструкцій. Не має значення, наскільки повільним буде мова або його віртуальна машина - всі вони мають загальну асимптоту. <Прим. пер. автор має на увазі, що навіть якщо зараз мова X в два рази повільніше Y, то в майбутньому після оптимізацій вони будуть приблизно рівні за швидкістю> Відповідно до цих міркувань можна сказати, що «швидкий» мову програмування всього лише передчасно оптимізований, причому незрозуміло за яким метрик.
оптимізуючи Python
Що мені подобається в Python, так це те, що він дозволяє оптимізувати невелику ділянку коду за раз. Припустимо, у вас є метод на Python, який ви вважаєте своїм вузьким місцем. Ви оптимізували його кілька разів, можливо, дотримуючись порад звідси і звідси , І тепер прийшли до висновку, що вже сам Python є вузьким місцем. Але він має можливість виклику коду на C, а це означає, що ви можете переписати цей метод на C, щоб зменшити проблему з продуктивністю. Ви без проблем можете використовувати цей метод разом з іншим кодом.
Це дозволяє писати добре оптимізовані методи вузьких місць на будь-якій мові, який компілюється в асемблерний код, тобто ви продовжуєте писати на Python більшу частину часу і переходите до низкорівневому програмування лише вам це дійсно потрібно.
Існує також мову Cython, який є надбезліччю Python. Він являє собою суміш з типізованим C. Будь-код Python є також дійсним кодом і на Cython, який транслюється в C. Ви можете змішувати типи C і качину типізацію. Використовуючи Cython, ви отримуєте приріст продуктивності тільки у вузькому місці, не переписуючи весь інший код. Так робить, наприклад, EVE Online . Ця MMoRPG використовує тільки Python і Cython для всього стека, проводячи оптимізацію тільки там, де це потрібно. Крім того, є й інші способи. наприклад, PyPy - реалізація JIT Python, яка може дати вам значне прискорення під час виконання довгоживучих додатків (наприклад, веб-сервера), просто шляхом заміни CPython (реалізація за замовчуванням) на PyPy.
Отже, основні моменти:
- оптимізуйте використання найдорожчого ресурсу - тобто вас, а не комп'ютера;
- вибирайте мову / фреймворк / архітектуру, яка дозволяє вам розробляти продукти якомога швидше. Не варто вибирати мову програмування лише тому, що програми на ньому працюють швидко;
- якщо у вас проблеми з продуктивністю - визначте, де саме;
- і, швидше за все, це не ресурси процесора або Python;
- якщо це все ж Python (і ви вже оптимізували алгоритм), реалізуйте проблемне місце на Cython / C;
- і швидше повертайтеся до основної роботи.
Дякую за увагу!
Так що, Python швидкий?Але що, якщо швидкість дійсно важлива?
Що може бути гірше з точки зору продуктивності ?
Що, якщо ми все-таки впираємося в CPU?
Що щодо таких аргументів: «Все це прекрасно, але що, якщо CPU стає вузьким місцем і це починає позначатися на продуктивності?
» Або «Мова x менш вимогливий до заліза, ніж y»?
Так що, Python швидкий?
Таким чином, залишається відкритим питання: чи швидше Python мови X під час розробки?