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: |

6How to manage your Telegram channel? In handing down the sentence yesterday, deputy judge Peter Hui Shiu-keung of the district court said that even if Ng did not post the messages, he cannot shirk responsibility as the owner and administrator of such a big group for allowing these messages that incite illegal behaviors to exist. Hui said the time period and nature of some offences “overlapped” and thus their prison terms could be served concurrently. The judge ordered Ng to be jailed for a total of six years and six months. With the administration mulling over limiting access to doxxing groups, a prominent Telegram doxxing group apparently went on a "revenge spree." Administrators
from us


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