# Python-ytelse: native NumPy-løkker, tilbakekall og konverteringskostnader

Published: 2026-10-17

En kontrollert CPU-kun numerisk test følger identiske verdier gjennom CPython-løkker, NumPy-aritmetikk, en Python-tilbakekall-wrapper og en kompilert Numba-løkke. Ferdig-input NumPy hadde et stort forsprang, mens konvertering fra og tilbake til Python-lister reduserte den fordelen til en nesten uavgjort. Episoden forklarer utførelsesgrensen og hvordan man måler resultatet en applikasjon trenger.

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

## Hva denne videoen dekker

- CPython kompilerer kildekode til bytecode. Gjenta tolk-/objektarbeid og en skrevet native numerisk løkke er forskjellige utførelsesarrangementer.
- Numerisk NumPy-aritmetikk kan gi typede grupper til kompilerte operasjoner; den aritmetiske løkken eksisterer fortsatt, og visninger kan ha ikke-sammenhengende oppsett.
- Mål konvertering og nødvendig utdatarepresentasjon. I denne kjøringen slettet konvertering av Python-lister til arrays og tilbake den store ledelsen for klare arrays.
- Små arbeidsmengder kan favorisere vanlig Python fordi faste kostnader for array-kall betyr noe. Forståelsen av åtte verdier vant denne målte sammenligningen.
- np.vectorize er en praktisk wrapper som kaller Python for suksessive elementer; et batch-grensesnitt alene etablerer ikke native numerisk utførelse.
- Kompilerte Python-syntaksløkker kan også være raske. Inkluder kostnader for kald kompilering/oppsett når de betyr noe for den som kaller.
- Native utførelse, CPU SIMD, multithreading og GPU-backends er separate ideer. Tilgjengelige CPU-funksjoner sporer ikke instruksjonene som brukes i en bestemt kjøring.

## Kapitler

- 0:00 Hvorfor kan samme CPU bli ferdig tidligere?
- 0:52 Hvilket arbeid gjentar en Python-løkke?
- 1:38 Hvor flytter NumPy løkken?
- 2:13 Betyr rask GPU eller mange CPU-kjerner?
- 2:49 Når forsvinner den imponerende hastighetsøkningen?
- 3:28 Hvilke grenser hører hjemme i benchmarken?
- 4:00 Kan en kompilert Python-løkke også være rask?
- 4:56 Hva utfører np.vectorize egentlig?
- 5:41 Hva bør du endre i koden din?

## Oversatt transkripsjon

Oversatt fra den originale engelske fortellingen. Tilgjengelig lyd og undertekster kontrolleres av YouTube.

### Hvorfor kan samme CPU bli ferdig tidligere?

0:00 Du tror Python trenger et nytt språk for å bli raskt. Den samme CPU-en kjørte vår batch raskere etter at løkken flyttet. Hvor ble det av arbeidet? Når forsvinner hastighetsøkningen? Hvilken snarvei bringer Python tilbake? Dette er The Daily Diff, under panseret. Hold et øye med den snarveien. CPython er standard Python-implementeringen.

0:17 Den kompilerer kildekoden din til bytecode, og kjører deretter disse instruksjonene i en tolker. NumPy er et numerisk bibliotek hvis arrays holder verdier med en deklarert datatype. Dens innebygde aritmetikk kan overlevere en hel batch til kompilerte operasjoner. Ta en million flytende komma-verdier, kvadrer hver enkelt, legg deretter til den opprinnelige verdien. Hver versjon får identiske verdier og produserer matchende svar. Verdiene er små nok til å holde avrundingsforskjeller utenfor løpet.

0:40 På denne maskinen tok forståelsen omtrent trettitre millisekunder. NumPy tok mindre enn én. Begge kjørte på CPUen. Det er nyttig bevis for denne arbeidsmengden, og en forferdelig nekrolog for et programmeringsspråk. Start med den vanlige løkken.

### Hvilket arbeid gjentar en Python-løkke?

0:53 Python får neste verdi, utfører aritmetikken og legger til svaret. Så gjør den det igjen. Multiplikasjonen er billig. Å arrangere neste multiplikasjon, og håndtere Python-objektene rundt den, legger til arbeid hver gang. Dette er den testede funksjonens faktiske disassemblering. Iterasjon, multiplikasjon og addisjon vises som bytecode-instruksjoner. Python-versjoner og tolker tar forskjellige valg.

1:14 Disse tidene tilhører versjonen på skjermen, som er Python 3.10. En Python-liste lagrer referanser til objekter, slik at forskjellige typer ting kan dele en liste. Vårt aritmetiske arbeid bruker tall gjennomgående. Det betaler for en generell ordning mens det ber om en repetitiv tjeneste. Se for deg å bestille den samme kaffen en million ganger og fylle ut et nytt skjema for hver kopp. Kaffemaskinen er fin.

1:36 Papirarbeidet har utviklet sin egen karriere.

### Hvor flytter NumPy løkken?

1:38 NumPy endrer kontrakten. Dette arrayet inneholder flyttallsverdier med fast størrelse og én deklarert type. Vårt array er sammenhengende, slik at verdiene ligger sammen i minnet. Visninger kan ha andre oppsett. Den aritmetiske operasjonen vet hva slags data den mottar. Kallet sender batchen til en native operasjon. En løkke besøker fortsatt verdiene inne i kompilert kode. Den kan gjenbruke kunnskap om typen på tvers av det arbeidet.

2:00 Python forblir personen som overleverer jobben. Itamar Turner Trauring forklarer skillet i Python Speed. Batch-grensesnitt, native implementasjoner og prosessorvektorinstruksjoner er separate ting. Funksjonsnavnet gir svært lite bevis.

### Betyr rask GPU eller mange CPU-kjerner?

2:13 Dette resultatet brukte NumPy på CPUen. En GPU-backend som CuPy velger et annet hjem for arrayer og operasjoner. Å kjøpe en GPU lar denne vanlige Python-løkken kjøre der den allerede kjørte. CPU-vektorinstruksjoner kan behandle flere verdier samtidig. NumPy har maskineri for å velge støttede kjerner. Vår kjøretid rapporterer tilgjengelige funksjoner, men sporer ikke denne uttrykkets instruksjoner. Å gi all den målte gevinsten til vektorinstruksjoner ville overselge beviset.

2:40 Handlekurven for GPU kan forbli lukket. Det er noe dypt tilfredsstillende med en ytelsesfiks som også avbryter et kjøp. Dessverre fortsetter referansen.

### Når forsvinner den imponerende hastighetsøkningen?

2:49 Med åtte verdier vant forståelsen. Å kalle array-maskineriet kostet mer enn den lille jobben. Større ferdige arrays dro foran. Vi brukte gjentatte forsøk og en oppvarmet prosess. Nyere Python-bygg kan endre overgangen. Endre deretter det applikasjonen trenger. Begynn med en Python-liste og avslutt med en fersk Python-liste. NumPy må konvertere inndata til et array og gjøre svaret tilbake til Python-objekter.

3:11 Disse trinnene hører hjemme på regningen hvis applikasjonen din trenger dem. Ved en million verdier tok den komplette stien omtrent tjueåtte millisekunder. Forståelsen tok også omtrent tjueåtte. Vårt dramatiske forsprang ble en nesten uavgjort. Den raske delen var ekte. Fordelen var avhengig av å la dataene forbli i sin numeriske form.

### Hvilke grenser hører hjemme i benchmarken?

3:28 Følg dataene. Hvis neste operasjon aksepterer et array, behold arrayet. Hvis du gjentatte ganger konverterer mellom lister og arrayer, mål disse kryssingene. Å stoppe før en kostbar overlevering gir nøyaktige tall for feil spørsmål. Å multiplisere dette arrayet skaper et midlertidig resultat. Å legge til de opprinnelige verdiene skaper utdataene. Native utførelse trenger fortsatt minne og flytter data.

3:47 Noen operasjoner aksepterer en utdatabuffer, noe som reduserer allokeringer når koden din kan trygt gjenbruke den. En pen linje kan bestille flere store buffere. Python Speed peker også på dette problemet. Allokatoren er bemerkelsesverdig likegyldig til din estetikk.

### Kan en kompilert Python-løkke også være rask?

4:00 Du kan også beholde løkkesyntaks og endre utførelsen. Numba kan kompilere støttede numeriske Python-funksjoner til native kode. Her er løkken fra testen vår med sin kompilatordekorator. Den sier fortsatt for. Den kostbare tolkstien har endret seg. Etter kompilering tok denne løkken mindre enn et halvt millisekund med ferdige arrays. Kompileringen tok selv omtrent et sekund i denne kjøringen. Den oppsettkostnaden ble ekskludert fra de gjentatte tidene,

4:22 så en liten engangsjobb fortjener en annen sammenligning. Numbas egen guide viser gjerne eksplisitte løkker. Å starte en språkoverføring før man finner den "varme stien" er en omstendelig måte å unngå å åpne en profiler. Først finn hva som forbruker tiden. Nettverksventetider, objektparsing og massearitmetikk krever forskjellige løsninger. Native array-operasjoner hjelper når beregningen og dataene passer.

4:43 Mål resultatet som den som kaller faktisk trenger. Nå for den snarveien. Du har en Python-funksjon og vil at den skal akseptere et array. En wrapper kalt vectorize høres ut som den manglende ytelsesknappen. Dokumentasjonen har en viktig setning som venter.

### Hva utfører np.vectorize egentlig?

4:56 NumPy sier at vectorize-wrapperen primært er gitt for enkelhets skyld. Implementeringen er i hovedsak en for-løkke. Wrapperen aksepterer batches, men fortsetter å kalle din Python-funksjon for suksessive elementer. Grensesnittet ble kortere. Utførelsesgrensen holdt seg travel. Se de samme verdiene komme tilbake via Python-tilbakekallingen. Med ferdige arrays tok denne versjonen omtrent åttisyv millisekunder. Den var tregere enn vår forståelse.

5:18 En nyttig kringkastings-wrapper kan bevare det eksakte per-element-arbeidet du prøvde å fjerne. fjerne. Sjekk implementeringen bak et batch-grensesnitt, behold kompatible data i sin nyttige form, og inkluder konvertering i sammenligningen. Native, callback- og kompilerte løkker kan se like ut fra den som kaller sin stol. Navnet vectorize ga et løfte din stoppeklokke aldri signerte. Behold det når bekvemmelighet er det du trenger. For ytelse, sjekk løkken som kjører.

### Hva bør du endre i koden din?

5:41 Min dom er SHIP IT for batching av en målt numerisk "hot path". Behold vanlige løkker når de allerede fungerer bra. Sjekk hvor arbeidet skjer og hva neste kaller trenger. Abonner, trykk på bjellen, og fortell meg i kommentarene om du ville ha stemplet det annerledes. Og det var The Daily Diff for i dag. Jeg er Niko fra Axrisi. Slå sammen ansvarlig.

## Kilder

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