Ez több művelet vagy adat feldolgozását igénylő feladat elvégzése során szükséges. Ezért néhány nem hatékony kódblokk és funkció kikapcsolása és javítása csodálatos eredményeket hozhat, például a következőket:
- Növelje az alkalmazás teljesítményét
- Hozzon létre olvasható és rendezett kódot
- Tegye egyszerűbbé a hibafigyelést és a hibakeresést
- Takarítson meg jelentős számítási teljesítményt és így tovább
Profilozza meg kódját
Az optimalizálás megkezdése előtt elengedhetetlen, hogy azonosítsuk a projektkód azon részeit, amelyek lassítják azt. A Python profilalkotási technikái közé tartozik a cProfile és a profilcsomagok. Használja ezeket az eszközöket annak mérésére, hogy bizonyos függvények és kódsorok milyen gyorsan futnak le. A cProfile modul jelentést készít, amely részletezi, mennyi ideig tart az egyes parancsfájlok futtatása. Ez a jelentés segíthet megtalálni a lassan futó funkciókat, és javítani tudjuk azokat.
Kódrészlet:
import cProfile mint cP
def számítsa összeget ( inputNumber ) :
bemeneti_számok_összege = 0
míg inputNumber > 0 :
bemeneti_számok_összege + = inputNumber % 10
inputNumber // = 10
nyomtatás ( 'A bemeneti szám összes számjegyének összege: 'bemeneti_számok_összege'' )
Visszatérés bemeneti_számok_összege
def main_func ( ) :
cP. fuss ( 'calculateSum(9876543789)' )
ha __név__ == '__fő__' :
main_func ( )
A program összesen öt függvényhívást hajt végre, ahogy az a kimenet első sorában látható. Az egyes függvényhívások részletei a következő néhány sorban láthatók, beleértve a függvény meghívásának számát, a függvény teljes időtartamát, a hívásonkénti időtartamot és a függvény teljes időtartamát (beleértve az összes olyan függvény, amelyet ennek hívnak).
Ezenkívül a program egy jelentést nyomtat a prompt képernyőn, amely azt mutatja, hogy a program 0,000 másodpercen belül befejezi az összes feladat végrehajtási idejét. Ez mutatja, milyen gyors a program.
Válassza ki a megfelelő adatstruktúrát
A teljesítményjellemzők az adatszerkezettől függenek. Különösen a szótárak gyorsabbak a kereséshez, mint a listák az általános célú tárolással kapcsolatban. Válassza ki azt az adatstruktúrát, amely a legmegfelelőbb az adatokkal végzett műveletekhez, ha ezeket ismeri. A következő példa a különböző adatstruktúrák hatékonyságát vizsgálja egy azonos folyamathoz annak meghatározására, hogy az adatszerkezetben van-e elem.
Kiértékeljük, hogy mennyi időbe telik annak ellenőrzése, hogy egy elem megtalálható-e az egyes adatstruktúrákban – listában, halmazban és szótárban –, és összehasonlítjuk őket.
OptimizeDataType.py:
import Timei mint ttimport véletlen mint rndobj
# Készítsen egész számok listáját
random_data_list = [ rndobj. randint ( 1 , 10000 ) számára _ ban ben hatótávolság ( 10000 ) ]
# Hozzon létre egy halmazt ugyanazokból az adatokból
random_data_set = készlet ( random_data_list )
# Hozzon létre egy szótárt ugyanazokkal az adatokkal, mint a kulcsokkal
obj_DataDictionary = { az egyiken: Egyik sem számára az egyiken ban ben random_data_list }
# Keresendő elem (van az adatokban)
véletlen_keresendő_szám = rndobj. választás ( random_data_list )
# Mérje meg a listában való tagság ellenőrzéséhez szükséges időt
list_time = tt. Timei ( lambda : véletlen_keresendő_szám ban ben random_data_list , szám = 1000 )
# Mérje meg az időt a készlet tagságának ellenőrzéséhez
beállítani az időt = tt. Timei ( lambda : véletlen_keresendő_szám ban ben random_data_set , szám = 1000 )
# Mérje meg a szótári tagság ellenőrzéséhez szükséges időt
dict_time = tt. Timei ( lambda : véletlen_keresendő_szám ban ben obj_DataDictionary , szám = 1000 )
nyomtatás ( f 'Listatagság ellenőrzési ideje: {list_time:.6f} másodperc' )
nyomtatás ( f 'Tagságellenőrzési idő beállítása: {set_time:.6f} másodperc' )
nyomtatás ( f 'A szótári tagság ellenőrzési ideje: {dict_time:.6f} másodperc' )
Ez a kód összehasonlítja a listák, készletek és szótárak teljesítményét a tagságellenőrzés során. Általánosságban elmondható, hogy a készletek és szótárak lényegesen gyorsabbak, mint a tagsági tesztek listái, mivel hash-alapú kereséseket használnak, így átlagos időbonyolításuk O(1). A listáknak ezzel szemben lineáris keresést kell végezniük, ami O(n) időbonyolultságú tagsági teszteket eredményez.
Használja a beépített függvényeket hurkok helyett
A Python számos beépített függvénye vagy metódusa használható olyan tipikus feladatok elvégzésére, mint a szűrés, rendezés és leképezés. Ezeknek a rutinoknak a használata a hurkok létrehozása helyett segít felgyorsítani a kódot, mivel gyakran teljesítményoptimalizáltak.
Készítsünk néhány mintakódot, hogy összehasonlíthassuk az egyéni hurkok létrehozásának teljesítményét a tipikus feladatok beépített függvényeinek felhasználásával (mint például a map(), a filter() és a sorted()). Értékeljük, hogy a különböző térképezési, szűrési és válogatási módszerek mennyire teljesítenek jól.
BuiltInFunctions.py:
import Timei mint tt# A numbers_list mintalistája
számok_lista = lista ( hatótávolság ( 1 , 10000 ) )
# Funkció a numbers_list négyzetre hurok használatával
def square_using_loop ( számok_lista ) :
négyzet_eredmény = [ ]
számára az egyiken ban ben numbers_list:
négyzet_eredmény. mellékel ( az egyiken** 2 )
Visszatérés négyzet_eredmény
# Funkció a páros számok_listájának ciklus segítségével történő szűrésére
def filter_even_using_loop ( számok_lista ) :
filter_result = [ ]
számára az egyiken ban ben numbers_list:
ha egy %-on 2 == 0 :
filter_result. mellékel ( az egyiken )
Visszatérés filter_result
# Funkció a numbers_list hurok segítségével történő rendezésére
def sort_using_loop ( számok_lista ) :
Visszatérés rendezve ( számok_lista )
# Mérje meg a négyzetszámok_listájához szükséges időt a map() segítségével
map_time = tt. Timei ( lambda : lista ( térkép ( lambda x: x ** 2 , számok_lista ) ) , szám = 1000 )
# Mérje meg a páros számok_lista szűrésének idejét a filter() segítségével
filter_time = tt. Timei ( lambda : lista ( szűrő ( lambda x: x % 2 == 0 , számok_lista ) ) , szám = 1000 )
# Mérje meg a numbers_list rendezéséhez szükséges időt a sorted() segítségével
rendezett_idő = tt. Timei ( lambda : rendezve ( számok_lista ) , szám = 1000 )
# Mérje meg a numbers_list négyzetbeállításának idejét hurok segítségével
loop_map_time = tt. Timei ( lambda : square_using_loop ( számok_lista ) , szám = 1000 )
# Mérje meg a páros számok_lista szűrésének idejét hurok segítségével
loop_filter_time = tt. Timei ( lambda : filter_even_using_loop ( számok_lista ) , szám = 1000 )
# Mérje meg a numbers_list rendezéséhez szükséges időt hurok segítségével
loop_sorted_time = tt. Timei ( lambda : sort_using_loop ( számok_lista ) , szám = 1000 )
nyomtatás ( 'A számlista 10000 elemet tartalmaz' )
nyomtatás ( f 'Map() idő: {map_time:.6f} másodperc' )
nyomtatás ( f 'Szűrő() idő: {filter_time:.6f} másodperc' )
nyomtatás ( f 'Rendezett() idő: {sorted_time:.6f} másodperc' )
nyomtatás ( f 'Hurok (térkép) ideje: {loop_map_time:.6f} másodperc' )
nyomtatás ( f 'Hurok (szűrő) idő: {loop_filter_time:.6f} másodperc' )
nyomtatás ( f 'Hurok (rendezési) idő: {loop_sorted_time:.6f} másodperc' )
Valószínűleg észre fogjuk venni, hogy a beépített függvények (map(), filter() és sorted()) gyorsabbak, mint az egyéni ciklusok ezekhez a gyakori feladatokhoz. A Python beépített funkciói tömörebb és érthetőbb megközelítést kínálnak ezeknek a feladatoknak a végrehajtásához, és rendkívül optimalizáltak a teljesítményre.
Optimalizálja a hurkokat
Ha szükséges a ciklusok írása, van néhány technika, amellyel felgyorsíthatjuk őket. Általában a range() ciklus gyorsabb, mint visszafelé. Ennek az az oka, hogy a range() a lista invertálása nélkül generál egy iterátort, ami hosszú listák esetén költséges művelet lehet. Ezenkívül, mivel a range() nem hoz létre új listát a memóriában, kevesebb memóriát használ.
OptimizeLoop.py:
import Timei mint tt# A numbers_list mintalistája
számok_lista = lista ( hatótávolság ( 1 , 100 000 ) )
# Funkció, amellyel a listát fordított sorrendben ismételheti
def loop_reverse_iteration ( ) :
eredmény_fordított = [ ]
számára j ban ben hatótávolság ( csak ( számok_lista ) - 1 , - 1 , - 1 ) :
eredmény_fordított. mellékel ( számok_lista [ j ] )
Visszatérés eredmény_fordított
# Funkció a listán a range() segítségével
def loop_range_iteration ( ) :
eredmény_tartomány = [ ]
számára k ban ben hatótávolság ( csak ( számok_lista ) ) :
eredmény_tartomány. mellékel ( számok_lista [ k ] )
Visszatérés eredmény_tartomány
# Mérje meg a fordított iteráció végrehajtásához szükséges időt
fordított_idő = tt. Timei ( loop_reverse_iteration , szám = 1000 )
# Mérje meg a tartományiteráció végrehajtásához szükséges időt
range_time = tt. Timei ( loop_range_iteration , szám = 1000 )
nyomtatás ( 'A számlista 100 000 rekordot tartalmaz' )
nyomtatás ( f 'Fordított iterációs idő: {reverse_time:.6f} másodperc' )
nyomtatás ( f 'Tartomány iterációs ideje: {range_time:.6f} másodperc' )
Kerülje a szükségtelen funkcióhívásokat
Valahányszor egy függvényt meghívnak, van némi többletköltség. A kód gyorsabban fut, ha elkerüljük a szükségtelen függvényhívásokat. Például egy értéket kiszámító függvény ismételt végrehajtása helyett próbálja meg eltárolni a számítás eredményét egy változóban, és azt használni.
Eszközök a profilalkotáshoz
Ha többet szeretne megtudni a kód teljesítményéről, a beépített profilalkotáson kívül használhatjuk a külső profilozó csomagokat, például a cProfile, Pyflame vagy SnakeViz.
Gyorsítótár eredmények
Ha a kódunknak költséges számításokat kell végrehajtania, időmegtakarítás céljából fontolóra veheti az eredmények gyorsítótárazását.
Kód refaktorálás
A kód átalakítása, hogy könnyebben olvasható és karbantartható legyen, néha az optimalizálás szükséges része. Egy gyorsabb program tisztább is lehet.
A Just-in-Time összeállítás (JIT) használata
Az olyan könyvtárak, mint a PyPy vagy a Numba, JIT-összeállítást biztosíthatnak, amely jelentősen felgyorsíthatja bizonyos típusú Python-kódokat.
Frissítse a Pythont
Győződjön meg arról, hogy a Python legújabb verzióját használja, mivel az újabb verziók gyakran tartalmaznak teljesítményjavításokat.
Párhuzamosság és párhuzamosság
A párhuzamosítható folyamatok esetében vizsgálja meg a párhuzamos és szinkronizálási technikákat, mint például a többfeldolgozás, a szálfűzés vagy az aszinkronizálás.
Ne feledje, hogy a teljesítményértékelésnek és a profilalkotásnak kell az optimalizálás fő mozgatórugóinak lennie. Koncentráljon kódunk azon területeinek fejlesztésére, amelyek a legjelentősebb hatással vannak a teljesítményre, és folyamatosan tesztelje fejlesztéseit, hogy megbizonyosodjon arról, hogy a kívánt hatást érik el anélkül, hogy további hibákat okoznának.
Következtetés
Összefoglalva, a Python-kód optimalizálása kulcsfontosságú a jobb teljesítmény és az erőforrás-hatékonyság szempontjából. A fejlesztők nagymértékben növelhetik Python-alkalmazásaik végrehajtási sebességét és válaszkészségét különféle technikák segítségével, például a megfelelő adatstruktúrák kiválasztásával, a beépített funkciók kihasználásával, az extra hurkok csökkentésével és a memória hatékony kezelésével. A folyamatos benchmarkingnak és profilalkotásnak kell irányítania az optimalizálási erőfeszítéseket, biztosítva, hogy a kódfejlesztések megfeleljenek a valós teljesítmény követelményeinek. A projekt hosszú távú sikerének garantálása és az új problémák bevezetésének esélyének csökkentése érdekében a kód optimalizálását folyamatosan egyensúlyban kell tartani a kód olvashatóságának és karbantarthatóságának céljaival.