Boost Python-koden: Samtidighet & Parallellisme forbedrer ytelsen!

Nøkkelpunkter

  • Samtidighet og parallellitet er fundamentale prinsipper for hvordan oppgaver utføres innen databehandling, og hver har sine egne spesifikke egenskaper.
  • Samtidighet muliggjør effektiv bruk av ressurser og forbedrer responsen for applikasjoner, mens parallellitet er kritisk for optimal ytelse og skalerbarhet.
  • Python tilbyr ulike måter å håndtere samtidighet på, som for eksempel tråder og asynkron programmering ved hjelp av `asyncio`, samt parallellitet ved bruk av `multiprocessing`-modulen.

Samtidighet og parallellitet er to metoder som tillater kjøring av flere programmer tilsynelatende samtidig. Python har flere alternativer for å administrere oppgaver både samtidig og parallelt, noe som kan være litt forvirrende.

Denne artikkelen utforsker verktøyene og bibliotekene som er tilgjengelige for korrekt implementering av samtidighet og parallellitet i Python, og ser på hvordan de skiller seg fra hverandre.

Forstå Samtidighet og Parallellitet

Samtidighet og parallellitet er to essensielle prinsipper for utførelse av oppgaver i databehandling. Hver av dem har sine egne særegne kjennetegn.

  • Samtidighet refererer til et programs evne til å administrere flere oppgaver samtidig uten at de nødvendigvis utføres nøyaktig samtidig. Det handler om å veksle mellom oppgaver på en slik måte at det ser ut som de kjører samtidig.
  • Parallellitet derimot, innebærer å faktisk kjøre flere oppgaver samtidig. Dette oppnås vanligvis ved å utnytte flere CPU-kjerner eller prosessorer. Parallellitet gir reell samtidig utførelse, som lar deg fullføre oppgaver raskere og er velegnet for beregningsintensive prosesser.
  • Betydningen av Samtidighet og Parallellitet

    Behovet for samtidighet og parallellitet innen databehandling kan ikke overvurderes. Her er hvorfor disse teknikkene er så viktige:

  • Ressursutnyttelse: Samtidighet bidrar til effektiv bruk av systemressurser, og sikrer at oppgaver gjør fremgang i stedet for å vente på eksterne ressurser.
  • Respons: Samtidighet kan forbedre responsen til applikasjoner, spesielt i situasjoner som involverer brukergrensesnitt eller webservere.
  • Ytelse: Parallellitet er avgjørende for å oppnå optimal ytelse, spesielt for CPU-krevende oppgaver som komplekse beregninger, dataanalyse og simuleringer.
  • Skalerbarhet: Både samtidighet og parallellitet er essensielle for å utvikle skalerbare systemer.
  • Fremtidssikring: Ettersom maskinvareutviklingen fortsetter å favorisere flerkjerneprosessorer, vil evnen til å utnytte parallellitet bli stadig mer nødvendig.
  • Samtidighet i Python

    Du kan oppnå samtidighet i Python ved hjelp av tråder og asynkron programmering med `asyncio`-biblioteket.

    Tråder i Python

    Tråder er en mekanisme for samtidighet i Python som lar deg opprette og håndtere oppgaver innenfor en enkelt prosess. Tråder er egnet for visse typer oppgaver, spesielt de som er I/O-bundet og kan dra nytte av samtidig utførelse.

    Pythons `threading`-modul gir et høynivågrensesnitt for å lage og administrere tråder. Selv om GIL (Global Interpreter Lock) begrenser tråder når det gjelder ekte parallellitet, kan de likevel oppnå samtidighet ved å veksle mellom oppgaver effektivt.

    Koden nedenfor viser et eksempel på hvordan samtidighet kan implementeres ved bruk av tråder. Den benytter Python-biblioteket `requests` for å sende HTTP-forespørsler, en typisk I/O-blokkerende oppgave. Den bruker også `time`-modulen for å beregne utførelsestiden.

     import requests
    import time
    import threading
    
    urls = [
        'https://www.google.com',
        'https://www.wikipedia.org',
        'https://www.makeuseof.com',
    ]
    
    def download_url(url):
        response = requests.get(url)
        print(f"Lastet ned {url} - Statuskode: {response.status_code}")
    
    start_time = time.time()
    
    for url in urls:
        download_url(url)
    
    end_time = time.time()
    print(f"Sekvensiell nedlasting tok {end_time - start_time:.2f} sekunder\n")
    
    start_time = time.time()
    threads = []
    
    for url in urls:
        thread = threading.Thread(target=download_url, args=(url,))
        thread.start()
        threads.append(thread)
    
    for thread in threads:
        thread.join()
    
    end_time = time.time()
    print(f"Trådet nedlasting tok {end_time - start_time:.2f} sekunder")
    

    Når du kjører dette programmet, vil du se hvor mye raskere de trådede forespørslene er sammenlignet med de sekvensielle forespørslene. Selv om forskjellen bare er en brøkdel av et sekund, får du en tydelig følelse av ytelsesforbedringen når du bruker tråder for I/O-bundne oppgaver.

    Asynkron Programmering med Asyncio

    `asyncio` tilbyr en hendelsesløkke som administrerer asynkrone oppgaver, kjent som korutiner. Korutiner er funksjoner som kan pauses og gjenopptas, noe som gjør dem ideelle for I/O-bundne oppgaver. Biblioteket er spesielt nyttig for scenarier der oppgaver krever venting på eksterne ressurser, for eksempel nettverksforespørsler.

    Du kan modifisere det forrige eksemplet med forespørselssending for å fungere med `asyncio`:

     import asyncio
    import aiohttp
    import time
    
    urls = [
        'https://www.google.com',
        'https://www.wikipedia.org',
        'https://www.makeuseof.com',
    ]
    
    async def download_url(url):
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as response:
                content = await response.text()
                print(f"Lastet ned {url} - Statuskode: {response.status}")
    
    async def main():
        tasks = [download_url(url) for url in urls]
        await asyncio.gather(*tasks)
    
    start_time = time.time()
    
    asyncio.run(main())
    
    end_time = time.time()
    
    print(f"Asyncio nedlasting tok {end_time - start_time:.2f} sekunder")
    

    Ved hjelp av denne koden kan du laste ned nettsider samtidig ved å bruke `asyncio` og dra nytte av asynkrone I/O-operasjoner. Dette kan være mer effektivt enn tråder for I/O-bundne oppgaver.

    Parallellitet i Python

    Du kan implementere parallellitet ved hjelp av Pythons `multiprocessing`-modul, som lar deg fullt ut utnytte flerkjerneprosessorer.

    Multiprosessering i Python

    Pythons `multiprocessing`-modul gir en måte å oppnå parallellitet på ved å opprette separate prosesser, hver med sin egen Python-tolk og minneplass. Dette omgår Global Interpreter Lock (GIL), noe som gjør den egnet for CPU-bundne oppgaver.

     import requests
    import multiprocessing
    import time
    
    urls = [
        'https://www.google.com',
        'https://www.wikipedia.org',
        'https://www.makeuseof.com',
    ]
    
    def download_url(url):
        response = requests.get(url)
        print(f"Lastet ned {url} - Statuskode: {response.status_code}")
    
    def main():
        num_processes = len(urls)
        pool = multiprocessing.Pool(processes=num_processes)
    
        start_time = time.time()
        pool.map(download_url, urls)
        end_time = time.time()
    
        pool.close()
        pool.join()
    
        print(f"Multiprosessering nedlasting tok {end_time-start_time:.2f} sekunder")
    
    main()
    

    I dette eksemplet oppretter multiprosessering flere prosesser, som gjør det mulig å kjøre `download_url`-funksjonen parallelt.

    Når Du Bør Bruke Samtidighet Eller Parallellitet

    Valget mellom samtidighet og parallellitet avhenger av hvilken type oppgaver du har og tilgjengelige maskinvareressurser.

    Du bør bruke samtidighet når du håndterer I/O-bundne oppgaver, som for eksempel lesing og skriving til filer eller nettverksforespørsler, og når minnebegrensninger er et problem.

    Bruk multiprosessering når du har CPU-bundne oppgaver som kan dra nytte av ekte parallellitet, og når du trenger robust isolasjon mellom oppgaver, der en feil i én oppgave ikke bør påvirke de andre.

    Utnytt Samtidighet og Parallellitet

    Parallellitet og samtidighet er effektive måter å forbedre responsen og ytelsen til Python-koden din. Det er viktig å forstå forskjellene mellom disse konseptene og velge den mest effektive strategien.

    Python tilbyr de nødvendige verktøyene og modulene for å gjøre koden din mer effektiv gjennom samtidighet eller parallellitet, uavhengig av om du arbeider med CPU- eller I/O-bundne prosesser.