# Python-prestaties: native NumPy-loops, callbacks en conversiekosten

Published: 2026-10-17

Een gecontroleerde, CPU-only numerieke test volgt identieke waarden door CPython-loops, NumPy-rekenkunde, een Python-callback-wrapper en een gecompileerde Numba-loop. Kant-en-klare NumPy had een grote voorsprong, terwijl conversie van en naar Python-lijsten dat voordeel reduceerde tot een bijna gelijkspel. De aflevering legt de uitvoeringsgrens uit en hoe het resultaat te meten dat een applicatie nodig heeft.

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

## Wat deze video behandelt

- CPython compileert broncode naar bytecode. Herhaald interpreter-/objectwerk en een getypte native numerieke loop zijn verschillende uitvoeringsarrangementen.
- Numerieke NumPy-rekenkunde kan getypte batches doorgeven aan gecompileerde bewerkingen; de rekenkundige loop bestaat nog steeds, en views kunnen niet-aaneengesloten lay-outs hebben.
- Meet conversie en de vereiste uitvoerrepresentatie. In deze run tenietgedaan het converteren van Python-lijsten naar arrays en terug de grote voorsprong van de kant-en-klare array.
- Kleine workloads kunnen gewone Python bevoordelen omdat vaste array-aanroepkosten van belang zijn. De comprehension met acht waarden won deze gemeten vergelijking.
- np.vectorize is een gemakswrapper die Python oproept voor opeenvolgende elementen; een batch-interface alleen creëert geen native numerieke uitvoering.
- Gecompileerde lussen met Python-syntax kunnen ook snel zijn. Neem de kosten voor koude compilatie/setup mee wanneer deze van belang zijn voor de aanroeper.
- Native uitvoering, CPU SIMD, multithreading en GPU-backends zijn aparte ideeën. Beschikbare CPU-functies traceren niet de instructies die in een bepaalde run worden gebruikt.

## Hoofdstukken

- 0:00 Waarom kan dezelfde CPU eerder klaar zijn?
- 0:52 Welk werk herhaalt een Python-loop?
- 1:38 Waar verplaatst NumPy de loop naartoe?
- 2:13 Betekent snel GPU of veel CPU-kernen?
- 2:49 Wanneer verdwijnt de indrukwekkende snelheidsverbetering?
- 3:28 Welke grenzen horen bij de benchmark?
- 4:00 Kan een gecompileerde Python-loop ook snel zijn?
- 4:56 Wat voert np.vectorize eigenlijk uit?
- 5:41 Wat moet je veranderen in je code?

## Vertaald transcript

Vertaald vanuit de originele Engelse gesproken tekst. Beschikbare audio en ondertiteling worden beheerd door YouTube.

### Waarom kan dezelfde CPU eerder klaar zijn?

0:00 Je denkt dat Python een nieuwe taal nodig heeft om snel te worden. Dezelfde CPU voerde onze batch sneller uit nadat de loop was verplaatst. Waar is het werk naartoe gegaan? Wanneer verdwijnt de snelheidsverbetering? Welke snelkoppeling brengt Python terug? Dit is The Daily Diff, onder de motorkap. Let op die snelkoppeling. CPython is de standaard Python-implementatie.

0:17 Het compileert je broncode naar bytecode en voert die instructies vervolgens uit in een interpreter. NumPy is een numerieke bibliotheek waarvan de arrays waarden bevatten met een gedeclareerd gegevenstype. De ingebouwde rekenkunde kan een hele batch doorgeven aan gecompileerde bewerkingen. Neem een miljoen drijvende-kommawaarden, kwadrateer elke waarde, voeg dan de oorspronkelijke waarde toe. Elke versie krijgt identieke waarden en produceert overeenkomende antwoorden. De waarden zijn klein genoeg om afrondingsverschillen buiten de race te houden.

0:40 Op deze machine duurde de comprehension ongeveer drieëndertig milliseconden. NumPy duurde minder dan één. Beide draaiden op de CPU. Dat is nuttig bewijs voor deze workload, en een vreselijk overlijdensbericht voor een programmeertaal. Begin met de gewone loop.

### Welk werk herhaalt een Python-loop?

0:53 Python haalt de volgende waarde op, voert de rekenkunde uit en voegt het antwoord toe. Dan doet het dat opnieuw. De vermenigvuldiging is goedkoop. Het regelen van de volgende vermenigvuldiging en het afhandelen van de Python-objecten eromheen, voegt elke keer werk toe. Dit is de daadwerkelijke demontage van de geteste functie. Iteratie, vermenigvuldiging en optelling verschijnen als bytecode-instructies. Python-versies en interpreters maken verschillende keuzes.

1:14 Deze tijden horen bij de versie op het scherm, dat is Python 3.10. Een Python-lijst slaat verwijzingen naar objecten op, zodat verschillende soorten dingen een lijst kunnen delen. Onze rekenkundige taak gebruikt overal getallen. Het betaalt voor een algemene regeling terwijl het een repetitieve service aanvraagt. Stel je voor dat je een miljoen keer dezelfde koffie bestelt en voor elke kop een nieuw formulier invult. De koffiemachine is prima.

1:36 Het papierwerk heeft zijn eigen carrière ontwikkeld.

### Waar verplaatst NumPy de loop naartoe?

1:38 NumPy verandert het contract. Deze array bevat drijvende-kommawaarden van vaste grootte met één gedeclareerd type. Onze array is aaneengesloten, dus de waarden liggen bij elkaar in het geheugen. Views kunnen andere lay-outs hebben. De rekenkundige bewerking weet welk type gegevens het ontvangt. De oproep geeft de batch door aan een native bewerking. Een loop bezoekt nog steeds de waarden binnen gecompileerde code. Het kan kennis van het type over dat werk hergebruiken.

2:00 Python blijft de persoon die de taak overhandigt. Itamar Turner Trauring legt het onderscheid uit in Python Speed. Batch-interfaces, native implementaties en processor vectorinstructies zijn aparte dingen. De functienaam levert zeer weinig bewijs.

### Betekent snel GPU of veel CPU-kernen?

2:13 Dit resultaat gebruikte NumPy op de CPU. Een GPU-backend zoals CuPy kiest een ander thuis voor arrays en bewerkingen. Het kopen van een GPU laat deze gewone Python-loop draaien waar hij al draaide. CPU-vectorinstructies kunnen meerdere waarden tegelijk verwerken. NumPy heeft mechanismen voor het kiezen van ondersteunde kernels. Onze runtime rapporteert beschikbare functies, maar traceert de instructies van deze uitdrukking niet. Het toekennen van de gehele gemeten winst aan vectorinstructies zou het bewijs overdrijven.

2:40 Het GPU-winkelwagentje kan gesloten blijven. Er is iets diep bevredigends aan een prestatieverbetering die ook een aankoop annuleert. Helaas gaat de benchmark door.

### Wanneer verdwijnt de indrukwekkende snelheidsverbetering?

2:49 Met acht waarden won de comprehension. Het aanroepen van de array-machinerie kostte meer dan de kleine taak. Grotere kant-en-klare arrays namen de leiding. We gebruikten herhaalde proeven en een opgewarmd proces. Nieuwere Python-builds kunnen de crossover veranderen. Verander dan wat de applicatie nodig heeft. Begin met een Python-lijst en eindig met een nieuwe Python-lijst. NumPy moet de invoer converteren naar een array en het antwoord weer omzetten naar Python-objecten.

3:11 Die stappen horen op de rekening als uw toepassing ze nodig heeft. Bij een miljoen waarden duurde dat complete pad ongeveer achtentwintig milliseconden. De comprehension duurde ook ongeveer achtentwintig. Onze dramatische voorsprong werd een bijna gelijkspel. Het snelle gedeelte was echt. Het voordeel hing af van het laten blijven van de gegevens in hun numerieke vorm.

### Welke grenzen horen bij de benchmark?

3:28 Volg de gegevens. Als de volgende bewerking een array accepteert, behoud de array dan. Als je herhaaldelijk converteert tussen lijsten en arrays, meet dan die overgangen. Stoppen voor een dure overdracht geeft nauwkeurige cijfers voor de verkeerde vraag. Het vermenigvuldigen van deze array creëert een tijdelijk resultaat. Het optellen van de oorspronkelijke waarden creëert de uitvoer. Native uitvoering heeft nog steeds geheugen en verplaatst gegevens nodig.

3:47 Sommige bewerkingen accepteren een uitvoerbuffer, waardoor allocaties worden verminderd wanneer uw code deze veilig kan hergebruiken. Eén mooie regel kan meerdere grote buffers bestellen. Python Speed wijst ook op dit probleem. De allocator is opmerkelijk onverschillig voor uw esthetiek.

### Kan een gecompileerde Python-loop ook snel zijn?

4:00 Je kunt ook de loop-syntax behouden en de uitvoering ervan wijzigen. Numba kan ondersteunde numerieke Python-functies compileren naar native code. Hier is de loop uit onze test met zijn compiler-decorator. Er staat nog steeds 'for'. Het dure interpreterpad is veranderd. Na compilatie duurde deze loop minder dan een halve milliseconde met kant-en-klare arrays. Compilatie zelf duurde in deze run ongeveer een seconde. Die setupkosten werden uitgesloten van de herhaalde metingen,

4:22 dus een kleine eenmalige taak verdient een andere vergelijking. De eigen gids van Numba toont graag expliciete loops. Het starten van een taalmigratie voordat het hete pad is gevonden, is een uitgebreide manier om het openen van een profiler te vermijden. Zoek eerst wat de tijd verbruikt. Netwerkwachttijden, objectparsing en bulkrekenkunde vragen om verschillende oplossingen. Native array-bewerkingen helpen wanneer de berekening en gegevens passen.

4:43 Meet het resultaat dat uw aanroeper daadwerkelijk nodig heeft. Nu die snelkoppeling. Je hebt een Python-functie en wilt dat deze een array accepteert. Een wrapper genaamd vectorize klinkt als de ontbrekende prestatieknop. De documentatie heeft een belangrijke zin in petto.

### Wat voert np.vectorize eigenlijk uit?

4:56 NumPy zegt dat zijn vectorize-wrapper voornamelijk voor het gemak wordt geleverd. De implementatie is in wezen een for-loop. De wrapper accepteert batches, maar blijft je Python-functie aanroepen voor opeenvolgende elementen. De interface werd korter. De uitvoeringsgrens bleef druk. Kijk hoe dezelfde waarden terugkomen via de Python-callback. Met kant-en-klare arrays duurde deze versie ongeveer zevenentachtig milliseconden. Het was langzamer dan onze comprehension.

5:18 Een nuttige broadcasting-wrapper kan precies het per-element werk behouden dat je probeerde te verwijderen. probeerde te verwijderen. Controleer de implementatie achter een batch-interface, bewaar compatibele gegevens in de nuttige vorm en neem conversie mee in de vergelijking. Native, callback en gecompileerde loops kunnen er vanuit de stoel van de aanroeper vergelijkbaar uitzien. De naam vectorize deed een belofte die je stopwatch nooit heeft ondertekend. Behoud het wanneer gemak is wat je nodig hebt. Voor prestaties, controleer de loop die draait.

### Wat moet je veranderen in je code?

5:41 Mijn oordeel is SHIP IT voor het batchen van een gemeten numeriek hot path. Behoud gewone loops wanneer ze al goed werken. Controleer waar het werk gebeurt en wat de volgende aanroeper nodig heeft. Abonneer, druk op de bel en vertel me in de reacties of je het anders zou hebben gestempeld. En dat is de diff voor vandaag. Ik ben Niko van Axrisi. Verantwoord samenvoegen.

## Bronnen

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