# Прадукцыйнасць Python: натыўныя цыклы NumPy, зваротныя выклікі і выдаткі на пераўтварэнне

Published: 2026-10-17

Кантраляваны лікавы тэст толькі для працэсара прасочвае ідэнтычныя значэнні праз цыклы CPython, арыфметыку NumPy, абалонку зваротнага выкліку Python і скампіляваны цыкл Numba. NumPy з гатовай наладай меў значную перавагу, у той час як пераўтварэнне з і ў спісы Python зменшыла гэтую перавагу да амаль роўнасці. Эпізод тлумачыць мяжу выканання і як вымяраць вынік, неабходны для прыкладання.

Canonical: https://thedailydiff.dev/be/video/2026-10-17-python-native-loops/

## Што ахоплівае гэта відэа

- CPython кампілюе зыходны код у байт-код. Паўторная праца інтэрпрэтатара/аб'екта і тыпізаваны натыўны лікавы цыкл - гэта розныя схемы выканання.
- Лікавая арыфметыка NumPy можа перадаваць тыпізаваныя пакеты ў скампіляваныя аперацыі; арыфметычны цыкл усё яшчэ існуе, і прадстаўленні могуць мець непаслядоўныя макеты.
- Вымерайце пераўтварэнне і неабходнае прадстаўленне вываду. У гэтым прагоне пераўтварэнне спісаў Python у масівы і назад сцёрла вялікую перавагу гатовага масіва.
- Малыя нагрузкі могуць спрыяць звычайнаму Python, таму што сталыя выдаткі на выклік масіваў маюць значэнне. Разуменне васьмі значэнняў выйграла гэта вымеранае параўнанне.
- np.vectorize - гэта зручная абалонка, якая выклікае Python для паслядоўных элементаў; толькі пакетны інтэрфейс не забяспечвае натыўнае лікавае выкананне.
- Скампіляваныя цыклы з сінтаксісам Python таксама могуць быць хуткімі. Уключайце выдаткі на халодную кампіляцыю/наладку, калі яны важныя для выклікальніка.
- Натыўнае выкананне, CPU SIMD, шматструменнасць і бэкэнды GPU - гэта асобныя ідэі. Даступныя функцыі CPU не адсочваюць інструкцыі, выкарыстаныя ў пэўным прагоне.

## Раздзелы

- 0:00 Чаму той жа працэсар можа скончыць раней?
- 0:52 Якую працу паўтарае цыкл Python?
- 1:38 Куды NumPy перамяшчае цыкл?
- 2:13 Ці азначае хуткасць GPU або шмат ядраў CPU?
- 2:49 Калі ўражлівае паскарэнне знікае?
- 3:28 Якія межы належаць да бенчмарка?
- 4:00 Ці можа скампіляваны цыкл Python быць хуткім таксама?
- 4:56 Што на самай справе выконвае np.vectorize?
- 5:41 Што вы павінны змяніць у сваім кодзе?

## Перакладзеная стэнаграма

Перакладзена з арыгінальнай англійскай агучкі. Даступнае аўдыя і субтытры кантралююцца YouTube.

### Чаму той жа працэсар можа скончыць раней?

0:00 Вы лічыце, што Python патрэбна новая мова, каб стаць хуткім. Той жа працэсар запусціў наш пакет хутчэй пасля перамяшчэння цыкла. Куды падзелася праца? Калі паскарэнне знікае? Які ярлык вяртае Python? Гэта The Daily Diff, пад капотам. Сачыце за гэтым ярлыком. CPython - гэта стандартная рэалізацыя Python.

0:17 Ён кампілюе ваш зыходны код у байт-код, затым выконвае гэтыя інструкцыі ў інтэрпрэтатары. NumPy - гэта лікавая бібліятэка, чые масівы захоўваюць значэнні з аб'яўленым тыпам даных. Яго ўбудаваная арыфметыка можа перадаваць цэлы пакет скампіляваным аперацыям. Возьмем мільён значэнняў з плаваючай кропкай, узвядзем кожнае ў квадрат, затым дадамо зыходнае значэнне. Кожная версія атрымлівае ідэнтычныя значэнні і выдае аднолькавыя адказы. Значэнні досыць малыя, каб выключыць розніцу ў акругленні з гонкі.

0:40 На гэтай машыне разуменне заняло каля трыццаці трох мілісекунд. NumPy заняў менш за адну. Абодва працавалі на працэсары. Гэта карыснае сведчанне для гэтай нагрузкі і жудасная некролог для мовы праграмавання. Пачнём са звычайнага цыкла.

### Якую працу паўтарае цыкл Python?

0:53 Python атрымлівае наступнае значэнне, выконвае арыфметыку і дадае адказ. Затым ён робіць гэта зноў. Множанне таннае. Арганізацыя наступнага множання і апрацоўка аб'ектаў Python вакол яго, дадае працу кожны раз. Гэта фактычная дызасемблея праверанай функцыі. Ітэрацыя, множанне і складанне з'яўляюцца як інструкцыі байт-коду. Версіі і інтэрпрэтатары Python робяць розны выбар.

1:14 Гэтыя таймінгі належаць да версіі на экране, гэта Python тры кропка дзесяць. Спіс Python захоўвае спасылкі на аб'екты, таму розныя віды рэчаў могуць падзяляць спіс. Нашая арыфметычная задача выкарыстоўвае лічбы на ўсім працягу. Яна плаціць за агульную дамоўленасць, запытваючы паўтаральную паслугу. Уявіце, што вы заказваеце адну і тую ж каву мільён разоў і запаўняеце новую форму для кожнай кубкі. Кавамашына ў парадку.

1:36 Дакументацыя развіла сваю ўласную кар'еру.

### Куды NumPy перамяшчае цыкл?

1:38 NumPy змяняе кантракт. Гэты масіў змяшчае значэнні з плаваючай кропкай фіксаванага памеру з адным аб'яўленым тыпам. Наш масіў сумежны, таму яго значэнні знаходзяцца разам у памяці. Прагляды могуць мець іншыя макеты. Арыфметычная аперацыя ведае, які тып дадзеных яна атрымлівае. Выклік перадае пакет натыўнай аперацыі. Цыкл усё яшчэ наведвае значэнні ў скампіляваным кодзе. Ён можа паўторна выкарыстоўваць веды аб тыпе для гэтай працы.

2:00 Python застаецца чалавекам, які перадае працу. Ітамар Тэрнер Траўрынг тлумачыць адрозненне ў Python Speed. Пакетныя інтэрфейсы, натыўныя рэалізацыі і вектарныя інструкцыі працэсара - гэта асобныя рэчы. Імя функцыі дае вельмі мала доказаў.

### Ці азначае хуткасць GPU або шмат ядраў CPU?

2:13 Гэты вынік выкарыстаў NumPy на працэсары. Бэкэнд GPU, такі як CuPy, выбірае іншае месца для масіваў і аперацый. Купля GPU пакідае гэты звычайны цыкл Python працаваць там, дзе ён ужо працаваў. Вектарныя інструкцыі CPU могуць апрацоўваць некалькі значэнняў разам. NumPy мае механізм для выбару падтрымліваемых ядраў. Наш час выканання паведамляе аб даступных функцыях, але не адсочвае інструкцыі гэтага выразу. Прысваенне ўсяго вымеранага прыросту вектарным інструкцыям было б перавышэннем доказаў.

2:40 Кошык для пакупак GPU можа заставацца закрытым. Ёсць нешта глыбока задавальняючае ў выпраўленні прадукцыйнасці, якое таксама адмяняе куплю. На жаль, бенчмарк працягваецца.

### Калі ўражлівае паскарэнне знікае?

2:49 З васьмю значэннямі разуменне выйграла. Выклік механізма масіваў каштаваў больш, чым мікраскапічная задача. Большыя гатовыя масівы вырваліся наперад. Мы выкарыстоўвалі паўторныя спробы і разагрэты працэс. Новыя зборкі Python могуць змяніць кропку перасячэння. Затым зменіце тое, што патрабуе прыкладанне. Пачніце са спісу Python і скончыце новым спісам Python. NumPy павінен пераўтварыць увод у масіў і вярнуць адказ у аб'екты Python.

3:11 Гэтыя крокі павінны быць у рахунку, калі ваша праграма іх патрабуе. Пры мільёне значэнняў гэты поўны шлях заняў каля дваццаці васьмі мілісекунд. Разуменне заняло каля дваццаці васьмі таксама. Наш драматычны адрыў стаў амаль нічыёй. Хуткая частка была рэальнай. Перавага залежала ад таго, каб дазволіць дадзеным заставацца ў іх лікавай форме.

### Якія межы належаць да бенчмарка?

3:28 Сачыце за дадзенымі. Калі наступная аперацыя прымае масіў, захавайце масіў. Калі вы шмат разоў пераўтвараеце паміж спісамі і масівамі, вымерайце гэтыя пераходы. Прыпынак перад дарагой перадачай дае дакладныя лічбы для няправільнага пытання. Множанне гэтага масіва стварае часовы вынік. Даданне зыходных значэнняў стварае вынік. Натыўнае выкананне па-ранейшаму патрабуе памяці і перамяшчае даныя.

3:47 Некаторыя аперацыі прымаюць выходны буфер, памяншаючы выдзяленне, калі ваш код можа бяспечна яго паўторна выкарыстоўваць. Адна прыгожая лінія можа замовіць некалькі вялікіх буфераў. Python Speed таксама звяртае ўвагу на гэтую праблему. Алакатар на дзіва абыякавы да вашай эстэтыкі.

### Ці можа скампіляваны цыкл Python быць хуткім таксама?

4:00 Вы таксама можаце захаваць сінтаксіс цыкла і змяніць яго выкананне. Numba можа кампіляваць падтрымліваныя лікавыя функцыі Python у натыўны код. Вось цыкл з нашага тэсту з яго дэкаратарам кампілятара. Ён усё яшчэ кажа for. Дарагі шлях інтэрпрэтатара змяніўся. Пасля кампіляцыі гэты цыкл заняў менш за паўмілісекунды з гатовымі масівамі. Сама кампіляцыя заняла каля секунды ў гэтым прагоне. Гэтыя выдаткі на наладу былі выключаны з паўторных замераў часу,

4:22 таму мікраскапічная разавая праца заслугоўвае іншага параўнання. Уласны даведнік Numba ахвотна дэманструе відавочныя цыклы. Пачатак міграцыі мовы да знаходжання гарачага шляху - гэта складаны спосаб пазбегнуць адкрыцця прафайлера. Спачатку знайдзіце, што спажывае час. Чаканні сеткі, аналіз аб'ектаў і масавыя арыфметычныя вылічэнні патрабуюць розных выпраўленняў. Натыўныя аперацыі з масівамі дапамагаюць, калі вылічэнне і даныя адпавядаюць.

4:43 Вымерайце вынік, які насамрэч патрэбны вашаму выклікальніку. Цяпер да таго ярлыка. У вас ёсць функцыя Python, і вы хочаце, каб яна прымала масіў. Абалонка пад назвай vectorize гучыць як прапушчаная кнопка прадукцыйнасці. Яго дакументацыя змяшчае важны сказ, які чакае.

### Што на самай справе выконвае np.vectorize?

4:56 NumPy сцвярджае, што яго абалонка vectorize прызначана ў асноўным для зручнасці. Яго рэалізацыя, па сутнасці, з'яўляецца цыклам for. Абалонка прымае пакеты, але працягвае выклікаць вашу функцыю Python для паслядоўных элементаў. Інтэрфейс стаў карацейшым. Мяжа выканання засталася загружанай. Паглядзіце, як тыя ж значэнні вяртаюцца праз зваротны выклік Python. З гатовымі масівамі гэтая версія заняла каля васьмідзесяці сямі мілісекунд. Яна была павольней, чым наша разуменне.

5:18 Карысная абалонка для рассылкі можа захаваць дакладную працу для кожнага элемента, якую вы спрабавалі выдаліць. Праверце рэалізацыю за пакетным інтэрфейсам, захоўвайце сумяшчальныя дадзеныя ў іх карыснай форме і ўключыце пераўтварэнне ў параўнанне. Натыўныя, зваротныя і скампіляваныя цыклы могуць выглядаць падобна з боку выклікальніка. Назва vectorize дала абяцанне, якое ваш секундамер ніколі не падпісваў. Захавайце яго, калі зручнасць - гэта тое, што вам трэба. Для прадукцыйнасці праверце цыкл, які выконваецца.

### Што вы павінны змяніць у сваім кодзе?

5:41 Маё рашэнне - SHIP IT для пакетнай апрацоўкі вымеранага лікавага гарачага шляху. Захоўвайце звычайныя цыклы, калі яны ўжо добра працуюць. Праверце, дзе адбываецца праца і што патрабуе наступны выклікальнік. Падпішыцеся, націсніце званочак і скажыце мне ў каментарах, калі б вы паставілі іншы штамп. І гэта ўсё на сёння. Я Ніко з Axrisi. Слівайце адказна.

## Крыніцы

- [Universal functions (ufunc) basics — NumPy 2.2](https://numpy.org/doc/2.2/user/basics.ufuncs.html) — NumPy
- [The N-dimensional array — NumPy 2.2](https://numpy.org/doc/2.2/reference/arrays.ndarray.html) — NumPy
- [numpy.vectorize — convenience and performance notes](https://numpy.org/doc/2.2/reference/generated/numpy.vectorize.html) — NumPy
- [CPU/SIMD optimizations — NumPy 2.2](https://numpy.org/doc/2.2/reference/simd/index.html) — NumPy
- [dis — Disassembler for Python bytecode](https://docs.python.org/3.10/library/dis.html) — Python Software Foundation
- [CPython 3.10.12 list representation](https://github.com/python/cpython/blob/v3.10.12/Include/cpython/listobject.h) — CPython contributors
- [The limits of Python vectorization as a performance technique](https://pythonspeed.com/articles/vectorization-python-alternatives/) — Itamar Turner-Trauring / Python⇒Speed
- [Performance Tips](https://numba.readthedocs.io/en/stable/user/performance-tips.html) — Numba
- [Basics of CuPy](https://docs.cupy.dev/en/stable/user_guide/basic.html) — CuPy
