PYPROGLIB Telegram 7017
👉 Мифы и сказки вокруг производительности Python

🔎 Миф 1: «Python не медленный» (а то мы не знали)

Многие считают, что Python достаточно быстр, ведь это язык-«клей», где для тяжёлых вычислений используют GPU или вызывают C/C++/Rust-библиотеки. Но на самом деле, для множества задач Python всё же медленен.

🔎 Миф 2: «Если медленно, перепиши горячие участки на C/C++/Rust»

Это действительно часто помогает — оптимизировать 20% кода, где происходит 80% работы (принцип Парето). Однако Amdahl's law говорит, что ускорение одной части программы в итоге упирается в остальной код. После ускорения «горячих» мест, всё остальное начинает доминировать по времени исполнения.

🔎 Миф 3: «Python медленный, потому что он интерпретируемый»

Интерпретация даёт некоторое замедление, но гораздо больше времени уходит на выполнение динамической семантики Python: поиск типов, вызовы методов вроде __getattribute__(), упаковку и распаковку значений, выделение памяти и т.д. Это не зависит от того, интерпретируется код или компилируется.

🔎 Статическая типизация и JIT — помогают, но не решают всё

Python набирает популярность с аннотациями типов, но статическая типизация не проверяется во время выполнения. Например:
def add(x: int, y: int) -> int:
return x + y

print(add('hello ', 'world')) # type: ignore


Здесь добавление строк работает, но не соответствует типам. Значит, оптимизации на основе типов невозможны в чистом Python.

JIT-компиляторы (например, в PyPy) действительно могут ускорить Python, но они усложняют предсказуемость производительности и требуют понимания, как именно JIT оптимизирует код. Иногда оптимизации «ломаются» при изменении программы, даже если код кажется простым.

🔎 Абстракции в Python — не бесплатны

Рассмотрим простой алгоритм:
def algo(points: list[tuple[float, float]]):
res = 0
for x, y in points:
res += x**2 * y + 10
return res


Если вынести вычисление в отдельную функцию:
def fn(x, y):
return x**2 * y + 10

def algo(points: list[tuple[float, float]]):
res = 0
for x, y in points:
res += fn(x, y)
return res


То производительность падает из-за накладных расходов на вызовы функций. Если вместо кортежей использовать @dataclass:
from dataclasses import dataclass

@dataclass
class Point:
x: float
y: float

def fn(p: Point):
return p.x**2 * p.y + 10

def algo(points: list[Point]):
res = 0
for p in points:
res += fn(p)
return res


Скорость падает ещё больше, потому что добавляется обращение к атрибутам объектов и накладные расходы, связанные с объектной моделью.

🔎 Кэш и память — главный узкий профиль

Основная проблема Python — не вычисления, а память. Современные процессоры быстро выполняют операции, но доступ к памяти (особенно к ОЗУ) намного медленнее.

Python-программы часто имеют плохую кэш-локалити из-за разброса объектов в памяти:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age

p = [Person('Alice', 16), Person('Bob', 21)]


В памяти объекты Person и их атрибуты могут быть разбросаны, что приводит к множеству переходов по указателям и к частым кеш-промахам.

Это проблема, которую невозможно решить только компиляцией или JIT, не изменяя семантику языка.

🔗 Если интересно, почему Python медленный, посмотрите подробный доклад: https://clc.to/YWmMIA

Библиотека питониста #буст
Please open Telegram to view this post
VIEW IN TELEGRAM
👍115🔥1😁1



tgoop.com/pyproglib/7017
Create:
Last Update:

👉 Мифы и сказки вокруг производительности Python

🔎 Миф 1: «Python не медленный» (а то мы не знали)

Многие считают, что Python достаточно быстр, ведь это язык-«клей», где для тяжёлых вычислений используют GPU или вызывают C/C++/Rust-библиотеки. Но на самом деле, для множества задач Python всё же медленен.

🔎 Миф 2: «Если медленно, перепиши горячие участки на C/C++/Rust»

Это действительно часто помогает — оптимизировать 20% кода, где происходит 80% работы (принцип Парето). Однако Amdahl's law говорит, что ускорение одной части программы в итоге упирается в остальной код. После ускорения «горячих» мест, всё остальное начинает доминировать по времени исполнения.

🔎 Миф 3: «Python медленный, потому что он интерпретируемый»

Интерпретация даёт некоторое замедление, но гораздо больше времени уходит на выполнение динамической семантики Python: поиск типов, вызовы методов вроде __getattribute__(), упаковку и распаковку значений, выделение памяти и т.д. Это не зависит от того, интерпретируется код или компилируется.

🔎 Статическая типизация и JIT — помогают, но не решают всё

Python набирает популярность с аннотациями типов, но статическая типизация не проверяется во время выполнения. Например:

def add(x: int, y: int) -> int:
return x + y

print(add('hello ', 'world')) # type: ignore


Здесь добавление строк работает, но не соответствует типам. Значит, оптимизации на основе типов невозможны в чистом Python.

JIT-компиляторы (например, в PyPy) действительно могут ускорить Python, но они усложняют предсказуемость производительности и требуют понимания, как именно JIT оптимизирует код. Иногда оптимизации «ломаются» при изменении программы, даже если код кажется простым.

🔎 Абстракции в Python — не бесплатны

Рассмотрим простой алгоритм:
def algo(points: list[tuple[float, float]]):
res = 0
for x, y in points:
res += x**2 * y + 10
return res


Если вынести вычисление в отдельную функцию:
def fn(x, y):
return x**2 * y + 10

def algo(points: list[tuple[float, float]]):
res = 0
for x, y in points:
res += fn(x, y)
return res


То производительность падает из-за накладных расходов на вызовы функций. Если вместо кортежей использовать @dataclass:
from dataclasses import dataclass

@dataclass
class Point:
x: float
y: float

def fn(p: Point):
return p.x**2 * p.y + 10

def algo(points: list[Point]):
res = 0
for p in points:
res += fn(p)
return res


Скорость падает ещё больше, потому что добавляется обращение к атрибутам объектов и накладные расходы, связанные с объектной моделью.

🔎 Кэш и память — главный узкий профиль

Основная проблема Python — не вычисления, а память. Современные процессоры быстро выполняют операции, но доступ к памяти (особенно к ОЗУ) намного медленнее.

Python-программы часто имеют плохую кэш-локалити из-за разброса объектов в памяти:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age

p = [Person('Alice', 16), Person('Bob', 21)]


В памяти объекты Person и их атрибуты могут быть разбросаны, что приводит к множеству переходов по указателям и к частым кеш-промахам.

Это проблема, которую невозможно решить только компиляцией или JIT, не изменяя семантику языка.

🔗 Если интересно, почему Python медленный, посмотрите подробный доклад: https://clc.to/YWmMIA

Библиотека питониста #буст

BY Библиотека питониста | Python, Django, Flask




Share with your friend now:
tgoop.com/pyproglib/7017

View MORE
Open in Telegram


Telegram News

Date: |

Among the requests, the Brazilian electoral Court wanted to know if they could obtain data on the origins of malicious content posted on the platform. According to the TSE, this would enable the authorities to track false content and identify the user responsible for publishing it in the first place. Add up to 50 administrators How to create a business channel on Telegram? (Tutorial) Image: Telegram. Each account can create up to 10 public channels
from us


Telegram Библиотека питониста | Python, Django, Flask
FROM American