Як зробити виконання мого Python швидшим

Деякі нотатки про погані справи

Фактори, що впливають на швидкість виконання Python

Інтерпретатор Python

Альтернативні інтерпретатори:

  • Перепишіть код у вигляді C-розширень або використовуйте Cython, який дозволяє писати швидкі розширення за синтаксисом, схожим на Python.
  • Використовуйте PyPy для компіляції Just-In-Time (JIT), що може значно пришвидшити роботу довготривалих додатків.

Версія має значення:

  • Завжди використовуйте останню стабільну версію Python для найкращих оптимізацій.

Віртуальне середовище

  • Допомагає уникнути конфліктів залежностей.
  • Запобігає впливу глобальних змінних на продуктивність бібліотек.
  • Забезпечує використання конкретних версій бібліотек для кращої продуктивності та стабільності.

Бенчмаркінг

  • Використовуйте інструменти, як-от timeit, cProfile або line_profiler, щоб визначити "вузькі місця".
  • Орієнтуйте зусилля з оптимізації на найповільніші частини вашого коду.

Техніки оптимізації швидкості

Оптимізації синтаксису

Вбудовані функції та бібліотеки

  • Вбудовані функції (наприклад, map) працюють швидше за цикли Python, оскільки вони реалізовані на C.
# Повільніший цикл  
newlist = [word.upper() for word in wordlist]  

# Швидше  
newlist = map(str.upper, wordlist)

Множинні присвоєння

  • Поєднуйте присвоєння в один рядок, щоб заощадити час на інтерпретації.
# Повільніше  
firstName = "John"  
lastName = "Henry"  
city = "Manchester"  

# Швидше  
firstName, lastName, city = "John", "Henry", "Manchester"

Спискові вирази

  • Використовуйте спискові вирази замість циклів для більш компактного та швидшого коду.
# Повільніший цикл  
newlist = []  
for i in range(1, 100):  
 if i % 2 == 0:  
 newlist.append(i**2)  

# Швидше  
newlist = [i**2 for i in range(1, 100) if i % 2 == 0]

Примусове визначення типів

  • Явно перетворюйте типи даних, щоб забезпечити ефективне виконання операцій.
x = y.astype(int)

Операції зі строками

  • Використовуйте join() для об'єднання рядків замість оператора +.
# Повільніше  
output = "Programming" + " is " + "fun"  

# Швидше  
output = " ".join(["Programming", "is", "fun"])

Оптимізація пам'яті

Попереднє виділення пам'яті

  • Виділяйте пам'ять один раз і повторно її використовуйте, щоб уникнути повторних виділень.
buffer = np.zeros((1000, 3)) # Попереднє виділення  

for i in range(1000):  
 buffer[i] = [1, 2, 3] # Оновлення на місці

Операції на місці

  • Змініть дані без створення нових копій.
# За межами місця  
y = x + 1 # Виділяється нова пам'ять  

# На місці  
x.add_(1) # Модифікує x безпосередньо

Зменшення передачі даних між CPU та GPU

  • Мінімізуйте передачу даних між CPU та GPU, обробляючи операції пакетами і зберігаючи дані на GPU.
x_gpu = x.to('cuda') # Перенесення на GPU

Ефективні імпорти

  • Уникайте непотрібних імпортів і використовуйте специфічні імпорти для часто використовуваних функцій.
# Повільніше  
import math  
value = math.sqrt(50)  

# Швидше  
from math import sqrt  
value = sqrt(50)

Оптимізація логіки та потоку

Умовні оператори

  • Уникайте непотрібних гілок (наприклад, if), щоб зменшити затримки в сучасних процесорах.

Попередньо обчислювана логіка

  • Кешуйте результати дорогих обчислень за допомогою functools.lru_cache.
from functools import lru_cache  

@lru_cache  
def expensive_computation(x):  
 return x**2

Конкурентність і паралелізм

Асинхронні операції

  • Використовуйте asyncio для задач, пов'язаних з I/O, таких як HTTP-запити.
import asyncio  
import httpx  

async def fetch(url):  
 async with httpx.AsyncClient() as client:  
 response = await client.get(url)  
 return response.text  

asyncio.run(fetch("https://example.com"))

Паралелізм

  • Використовуйте concurrent.futures для паралельного виконання в задачах, пов'язаних з процесором.
from concurrent.futures import ProcessPoolExecutor  

with ProcessPoolExecutor() as executor:  
 results = list(executor.map(func, data))

Оптимізація HTTP-запитів

Постійні з'єднання

  • Повторно використовуйте з'єднання за допомогою requests.Session() або httpx.Client().

Пакетні запити

  • Групуйте кілька API-запитів в один пакет, коли це можливо.

Використання WebSockets

  • Замініть повторювані опитування WebSockets для реального часу.
    ## Розширені інструменти та техніки

Numba

  • Прискорюйте числові обчислення за допомогою Numba.
from numba import jit  

@jit  
def fast_function(x):  
 return x**2

Cython

  • Перетворюйте код Python у C для критичних за продуктивністю ділянок коду.

Оптимізація апаратного забезпечення

  • Використовуйте Linux для кращої продуктивності порівняно з Windows.
  • Увімкніть режим продуктивності процесора в операційній системі.
  • Розгортайте додатки ближче до цільових серверів, щоб зменшити затримку.

Перекладено з: How to Make My Python Run Faster

Leave a Reply

Your email address will not be published. Required fields are marked *