# Python teljesítmény: natív NumPy ciklusok, visszahívások és konverziós költségek

Published: 2026-10-17

Egy kontrollált, csak CPU-t használó numerikus teszt azonos értékeket követ nyomon CPython ciklusokon, NumPy aritmetikán, egy Python visszahívó "wrapperen" és egy fordított Numba cikluson keresztül. A készen álló bemeneti NumPy nagy előnnyel rendelkezett, míg a Python listákból való átalakítás és visszaalakítás közel holtversenyre csökkentette ezt az előnyt. Az epizód elmagyarázza a végrehajtási határt és azt, hogyan mérje meg az alkalmazásnak szükséges eredményt.

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

## Amit ez a videó tartalmaz

- A CPython a forráskódot bájtkódra fordítja. Az ismételt interpreter/objektum munka és egy típusos natív numerikus ciklus eltérő végrehajtási elrendezések.
- A numerikus NumPy aritmetika típusos kötegeket adhat át fordított műveleteknek; az aritmetikai ciklus továbbra is létezik, és a nézeteknek lehetnek nem összefüggő elrendezései.
- Mérje meg az átalakítást és a szükséges kimeneti reprezentációt. Ebben a futtatásban a Python listák tömbe való átalakítása és visszaalakítása eltüntette a nagy 'kész tömb' előnyt.
- A kis terhelések kedvezhetnek a hagyományos Pythonnak, mert a rögzített tömb-hívási költségek számítanak. A nyolc értékből álló listabeszorítás nyerte ezt a mért összehasonlítást.
- Az np.vectorize egy kényelmi wrapper, amely egymást követő elemekre hívja a Pythont; önmagában egy kötegelt interfész nem biztosít natív numerikus végrehajtást.
- A fordított Python-szintaxisú ciklusok is gyorsak lehetnek. Vegye figyelembe a hideg fordítási/beállítási költségeket, ha azok számítanak a hívó számára.
- A natív végrehajtás, a CPU SIMD, a többszálasítás és a GPU háttérprogramok különálló elképzelések. A rendelkezésre álló CPU funkciók nem követik nyomon a adott futtatásban használt utasításokat.

## Fejezetek

- 0:00 Miért végezhet hamarabb ugyanaz a CPU?
- 0:52 Milyen munkát ismétel egy Python ciklus?
- 1:38 Hová helyezi át a NumPy a ciklust?
- 2:13 A gyors jelent GPU-t vagy sok CPU magot?
- 2:49 Mikor tűnik el a lenyűgöző sebességnövekedés?
- 3:28 Mely határok tartoznak a benchmarkba?
- 4:00 Lehet gyors egy fordított Python ciklus is?
- 4:56 Mit is hajt végre valójában az np.vectorize?
- 5:41 Mit kellene megváltoztatnia a kódjában?

## Lefordított átirat

Az eredeti angol narrációból fordítva. A rendelkezésre álló hangot és feliratokat a YouTube vezérli.

### Miért végezhet hamarabb ugyanaz a CPU?

0:00 Azt hiszi, hogy Pythonnak új nyelvre van szüksége a gyorsasághoz. Ugyanaz a CPU gyorsabban futtatta a kötegünket, miután a ciklus átkerült. Hová tűnt a munka? Mikor tűnik el a sebességnövekedés? Melyik parancsikon hozza vissza a Pythont? Ez a The Daily Diff, a felszín alatt. Tartsa szemmel azt a parancsikont. A CPython a standard Python implementáció.

0:17 A forráskódot bájtkódra fordítja, majd ezeket az utasításokat egy interpreterben futtatja. A NumPy egy numerikus könyvtár, melynek tömbjei deklarált adattípusú értékeket tárolnak. A beépített aritmetikája egy egész köteget adhat át fordított műveleteknek. Vegyünk egymillió lebegőpontos értéket, négyzeteljük mindegyiket, majd adjuk hozzá az eredeti értéket. Minden verzió azonos értékeket kap és egyező válaszokat produkál. Az értékek elég kicsik ahhoz, hogy a kerekítési különbségeket kizárják a versenyből. Ezen a gépen a listabeszorítás körülbelül harminchárom milliszekundumot vett igénybe.

0:40 A NumPy kevesebb mint egyet. Mindkettő a CPU-n futott. Ez hasznos bizonyíték erre a munkaterhelésre, és szörnyű nekrológ egy programozási nyelv számára. Kezdjük a szokásos ciklussal. A Python megkapja a következő értéket, elvégzi az aritmetikát, és hozzáadja az eredményt.

### Milyen munkát ismétel egy Python ciklus?

0:53 Aztán újra megteszi. A szorzás olcsó. A következő szorzás előkészítése, és a körülötte lévő Python objektumok kezelése minden alkalommal munkát ad hozzá. Ez a tesztelt függvény tényleges szétszerelése. Az iteráció, a szorzás és az összeadás bájtkód-utasításként jelennek meg. A Python verziók és interpretek eltérő döntéseket hoznak. Ezek az időzítések a képernyőn látható verzióhoz tartoznak, ami a Python 3.10.

1:14 Egy Python lista objektumokra mutató hivatkozásokat tárol, így különböző típusú dolgok megoszthatnak egy listát. A mi aritmetikai feladatunkban végig számok szerepelnek. Egy általános elrendezésért fizet, miközben ismétlődő szolgáltatást kér. Képzelje el, hogy egymillió alkalommal rendel ugyanazt a kávét, és minden csésze esetén kitölt egy új űrlapot. A kávégép rendben van. Az adminisztráció saját karriert futott be. A kávégép rendben van.

1:36 Az adminisztráció saját karriert futott be.

### Hová helyezi át a NumPy a ciklust?

1:38 A NumPy megváltoztatja a szerződést. Ez a tömb rögzített méretű lebegőpontos értékeket tartalmaz, egy deklarált típussal. A tömbünk összefüggő, így értékei együtt helyezkednek el a memóriában. A nézeteknek lehetnek más elrendezései. Az aritmetikai művelet tudja, milyen típusú adatot kap. A hívás a köteget egy natív műveletnek adja át. Egy ciklus továbbra is végigjárja az értékeket a fordított kódon belül. Ez a munka során újra felhasználhatja a típusra vonatkozó tudást.

2:00 A Python marad az, aki átadja a munkát. Itamar Turner Trauring a Python Speed-ben magyarázza a különbséget. A kötegelt interfészek, a natív implementációk és a processzor vektoros utasításai különböző dolgok. A függvény neve nagyon kevés bizonyítékot szolgáltat.

### A gyors jelent GPU-t vagy sok CPU magot?

2:13 Ez az eredmény NumPy-t használt a CPU-n. Egy GPU backend, mint a CuPy, más helyet választ a tömböknek és műveleteknek. A GPU vásárlása meghagyja ezt a szokásos Python ciklust ott, ahol már futott. A CPU vektoros utasításai több értéket is feldolgozhatnak egyszerre. A NumPy rendelkezik mechanizmussal a támogatott kernelek kiválasztására. A futási időnk jelenti a rendelkezésre álló funkciókat, de nem követi nyomon ennek a kifejezésnek az utasításait. Az összes mért nyereség vektoros utasításoknak való tulajdonítása túlértékelné a bizonyítékokat.

2:40 A GPU bevásárlókosár maradhat zárva. Van valami mélyen kielégítő abban, ha egy teljesítményjavítás egyben egy vásárlást is megakadályoz. Sajnos a benchmark folytatódik.

### Mikor tűnik el a lenyűgöző sebességnövekedés?

2:49 Nyolc értékkel a listabeszorítás nyert. A tömbmechanizmus hívása többe került, mint az apró feladat. A nagyobb, készen álló tömbök előnyt szereztek. Ismételt futtatásokat és egy bemelegített folyamatot használtunk. Az újabb Python fordítások megváltoztathatják a keresztezést. Majd változtassuk meg, mire van szüksége az alkalmazásnak. Kezdje egy Python listával, és fejezze be egy friss Python listával. A NumPy-nak át kell alakítania a bemenetet tömbbé, és a választ vissza kell alakítania Python

3:11 objektumokká. Ezek a lépések felkerülnek a számlára, ha az alkalmazása igényli őket. Egy millió értékkel ez a teljes útvonal körülbelül huszonnyolc milliszekundumot vett igénybe. A listabeszorítás is körülbelül huszonnyolc milliszekundumot. A drámai előnyünk közel holtversennyé vált. A gyors rész valós volt. Az előny azon múlott, hogy az adatok megmaradhattak numerikus formában.

### Mely határok tartoznak a benchmarkba?

3:28 Kövesse az adatokat. Ha a következő művelet tömböt fogad el, tartsa meg a tömböt. Ha ismételten konvertál listák és tömbök között, mérje meg ezeket az átmeneteket. Egy drága átadás előtt leállva pontos számokat kapunk a rossz kérdésre. Ennek a tömbnek a szorzása ideiglenes eredményt hoz létre. Az eredeti értékek hozzáadása hozza létre a kimenetet. A natív végrehajtáshoz továbbra is memória és adatmozgás szükséges.

3:47 Néhány művelet elfogad egy kimeneti puffert, csökkentve az allokációkat, ha a kódja biztonságosan újra felhasználhatja azt. Egy szép sor több nagy puffert is megrendelhet. A Python Speed is kiemeli ezt a problémát. Az allokátor rendkívül közömbös az esztétikájával szemben.

### Lehet gyors egy fordított Python ciklus is?

4:00 Megtarthatja a ciklus szintaxisát és megváltoztathatja a végrehajtását is. A Numba a támogatott numerikus Python függvényeket natív kóddá fordíthatja. Itt van a tesztünk ciklusa a fordító dekorátorral. Még mindig azt mondja, hogy 'for'. A drága interpreter útvonal megváltozott. A fordítás után ez a ciklus kevesebb mint fél milliszekundumot vett igénybe készen álló tömbökkel. Maga a fordítás körülbelül egy másodpercet vett igénybe ebben a futtatásban. Ezt a beállítási költséget kizárták az ismételt időzítésekből,

4:22 így egy apró egyszeri feladat más összehasonlítást érdemel. A Numba saját útmutatója szívesen mutat explicit ciklusokat. Nyelvváltás megkezdése a hot path megtalálása előtt egy bonyolult módja annak, hogy elkerülje a profilozó megnyitását. Először derítse ki, mi emészti fel az időt. A hálózati várakozások, az objektumok elemzése és a tömeges aritmetika eltérő javításokat igényel. A natív tömbműveletek segítenek, ha a számítás és az adatok illeszkednek.

4:43 Mérje meg azt az eredményt, amire a hívónak ténylegesen szüksége van. Most jöjjön az a parancsikon. Van egy Python függvénye, és azt szeretné, hogy tömböt fogadjon el. A vectorize nevű wrapper úgy hangzik, mint a hiányzó teljesítménygomb. A dokumentációjában egy fontos mondat vár.

### Mit is hajt végre valójában az np.vectorize?

4:56 A NumPy szerint a vectorize wrapper elsősorban a kényelem kedvéért készült. Az implementációja lényegében egy 'for' ciklus. A wrapper elfogadja a kötegeket, de továbbra is meghívja a Python függvényt az egymást követő elemekhez. Az interfész rövidebb lett. A végrehajtási határ továbbra is elfoglalt maradt. Nézze meg, ahogy ugyanazok az értékek visszatérnek a Python visszahívásán keresztül. Készen álló tömbökkel ez a verzió körülbelül nyolcvanhét milliszekundumot vett igénybe. Lassabb volt, mint a listabeszorításunk.

5:18 Egy hasznos "broadcasting" wrapper megőrizheti az exact, elemenkénti munkát, amelyet megpróbált eltávolítani. Ellenőrizze a kötegelt interfész mögötti implementációt, tartsa a kompatibilis adatokat a hasznos formájában, és vegye figyelembe az átalakítást az összehasonlításban. A natív, visszahívó és fordított ciklusok hasonlóan nézhetnek ki a hívó székéből. A vectorize név olyan ígéretet tett, amit a stopperóra soha nem írt alá. Tartsa meg, ha a kényelemre van szüksége. A teljesítmény érdekében ellenőrizze a futó ciklust.

### Mit kellene megváltoztatnia a kódjában?

5:41 Az ítéletem: SHIP IT a mért numerikus hot path kötegelésére. Tartsa meg a szokásos ciklusokat, ha már jól működnek. Ellenőrizze, hol történik a munka és mire van szüksége a következő hívónak. Iratkozz fel, nyomd meg a harangot, és írd meg kommentben, ha másképp bélyegezted volna. És ez a mai különbség. Niko vagyok az Axrisi-től. Felelősen egyesítsen.

## Források

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