Vītņošana ievērojami samazina programmas izpildes laiku. Uzziniet, kā Python ieviest pavedienu veidošanu.

Izpildes laiks ir viens no izplatītākajiem programmas efektivitātes rādītājiem. Jo ātrāks izpildes laiks, jo labāka programma. Vītņošana ir paņēmiens, kas ļauj programmai vienlaikus veikt vairākus uzdevumus vai procesus.

Jūs uzzināsit, kā izmantot iebūvēto Python vītņošana modulis un vienlaikus.iezīmes modulis. Abi šie moduļi piedāvā vienkāršus veidus, kā izveidot un pārvaldīt pavedienus

Vītņu veidošanas nozīme

Vītņošana samazina laiku, kas programmai nepieciešams, lai pabeigtu darbu. Ja uzdevums ietver vairākus neatkarīgus uzdevumus, varat izmantot pavedienu veidošanu, lai uzdevumus izpildītu vienlaikus, samazinot programmas gaidīšanas laiku, līdz viens uzdevums tiks pabeigts, pirms pāriet uz nākamo.

Piemēram, programma, kas no interneta lejupielādē vairākus attēlu failus. Šī programma var izmantot pavedienu veidošanu, lai lejupielādētu failus paralēli, nevis pa vienam. Tas novērš laiku, kas programmai jāgaida, līdz viena faila lejupielādes process tiks pabeigts, pirms pāriet uz nākamo.

Sākotnējā programma pirms vītņošanas

Funkcija šajā programmā apzīmē uzdevumu. Uzdevums ir uz vienu sekundi apturēt programmas izpildi. Programma divreiz izsauc funkciju, tādējādi izveidojot divus uzdevumus. Pēc tam tas aprēķina laiku, kas bija nepieciešams visas programmas palaišanai, un pēc tam parāda to ekrānā.

imports laiks

sākuma_laiks = laiks.perf_skaitītājs()

defpauze():
drukāt ("Guļ 1 sekundi...")
time.sleep(1)
drukāt ("Pabeidzu gulēt...")

pauze ()
pauze ()
finiša_laiks = laiks.perf_skaitītājs()
drukāt (f'Pabeigts {raunds (finish_time - start_time, 2)} otrais (s)")

Izvade parāda, ka programmas izpildei bija nepieciešama 2,01 sekunde. Katrs uzdevums aizņēma vienu sekundi, bet pārējā koda izpildei bija nepieciešama 0,01 sekunde.

Varat izmantot pavedienu veidošanu, lai vienlaikus izpildītu abus uzdevumus. Abu uzdevumu izpilde prasīs vienu sekundi.

Vītņošanas ieviešana, izmantojot vītņu moduli

Lai modificētu sākotnējo kodu, lai ieviestu pavedienu, importējiet vītņošana modulis. Izveidojiet divus pavedienus, pavediens_1 un pavediens_2 izmantojot Pavediens klasē. Zvaniet uz sākt metodi katrā pavedienā, lai sāktu tā izpildi. Zvaniet uz pievienoties metodi katrā pavedienā, lai gaidītu to izpildes pabeigšanu, pirms tiek izpildīta pārējā programma.

imports laiks
imports vītņošana
sākuma_laiks = laiks.perf_skaitītājs()

defpauze():
drukāt ("Guļ 1 sekundi...")
time.sleep(1)
drukāt ("Pabeidzu gulēt...")

pavediens_1 = pavediens. Pavediens (target=pause)
pavediens_2 = pavediens. Pavediens (target=pause)

pavediens_1.sākt()
pavediens_2.start()

pavediens_1.pievienoties()
pavediens_2.pievienoties()

finiša_laiks = laiks.perf_skaitītājs()
drukāt (f'Pabeigts {raunds (finish_time - start_time, 2)} otrais (s)")

Programma vienlaikus darbos abus pavedienus. Tas samazinās laiku, kas nepieciešams abu uzdevumu veikšanai.

Izvade parāda, ka laiks, kas nepieciešams, lai izpildītu tos pašus uzdevumus, ir aptuveni sekunde. Tas ir puse no sākotnējās programmas laika.

Threading ieviešana, izmantojot concurrent.futures moduli

Python 3.2 tika ieviests vienlaikus.nākotnes modulis. Šis modulis nodrošina augsta līmeņa saskarni asinhronu uzdevumu izpildei, izmantojot pavedienus. Tas nodrošina vienkāršāku veidu, kā paralēli veikt uzdevumus.

Lai modificētu sākotnējo programmu, lai izmantotu pavedienu veidošanu, importējiet moduli concurrent.features. Izmantojiet ThreadPoolExecutor klases no concurrent.futures moduļa, lai izveidotu pavedienu kopu. Iesniedziet pauze funkcija uz baseinu divas reizes. The Iesniegt metode atgriež a nākotnē objekts, kas attēlo funkcijas izsaukuma rezultātu.

Atkārtojiet pāri nākotnes līgumi un izdrukājiet rezultātus, izmantojot rezultāts metodi.

imports laiks
imports vienlaikus.nākotnes

sākuma_laiks = laiks.perf_skaitītājs()

defpauze():
drukāt ("Guļ 1 sekundi...")
time.sleep(1)
atgriezties"Pabeidzu gulēt..."

ar vienlaikus.nākotnes. ThreadPoolExecutor() izpildītājs:
rezultāti = [executor.submit (pauze) priekš _ iekšā diapazons(2)]
priekš f iekšā concurrent.futures.as_completed (rezultāti):
drukāt (f.result())

finiša_laiks = laiks.perf_skaitītājs()

drukāt (f'Pabeigts {raunds (finish_time - start_time, 2)} otrais (s)")

Concurrent.features modulis rūpējas par pavedienu sākšanu un savienošanu jūsu vietā. Tas padara jūsu kodu tīrāku.

Izvade ir identiska vītņošanas moduļa izvadei. Vītņu veidošanas modulis ir noderīgs vienkāršos gadījumos, kad paralēli jāpavada daži pavedieni. No otras puses, concurrent.futures modulis ir noderīgs sarežģītākos gadījumos, kad vienlaikus jāpalaiž daudzi uzdevumi.

Vītņu izmantošana reālās pasaules scenārijā

Izmantojot pavedienus, lai palaistu iepriekš minēto programmu, laiks tika samazināts par vienu sekundi. Reālajā pasaulē pavedieni ietaupa vairāk laika. Izveidojiet programmu, kas lejupielādē attēlus no interneta. Sāciet ar jaunas virtuālās vides izveide. Lai instalētu, terminālī izpildiet šo komandu pieprasījumus bibliotēka:

pip instalēšanas pieprasījumi

Pieprasījumu bibliotēka ļaus nosūtīt HTTP pieprasījumus. Importējiet pieprasījumu bibliotēku un laika bibliotēku.

imports pieprasījumus
imports laiks

Izveidojiet to attēlu vietrāžu URL sarakstu, kurus vēlaties lejupielādēt. Ļaujiet tiem būt vismaz desmit, lai jūs varētu pamanīt būtisku atšķirību, ieviešot pavedienu.

img_urls = [
' https://images.unsplash.com/photo-1524429656589-6633a470097c',
' https://images.unsplash.com/photo-1530224264768-7ff8c1789d79',
' https://images.unsplash.com/photo-1564135624576-c5c88640f235',
' https://images.unsplash.com/photo-1541698444083-023c97d3f4b6',
' https://images.unsplash.com/photo-1522364723953-452d3431c267',
' https://images.unsplash.com/photo-1513938709626-033611b8cc03',
' https://images.unsplash.com/photo-1507143550189-fed454f93097',
' https://images.unsplash.com/photo-1493976040374-85c8e12f0c0e',
' https://images.unsplash.com/photo-1504198453319-5ce911bafcde',
' https://images.unsplash.com/photo-1530122037265-a5f1f91d3b99',
' https://images.unsplash.com/photo-1516972810927-80185027ca84',
' https://images.unsplash.com/photo-1550439062-609e1531270e',
]

Pārlūkojiet sarakstu URL, kas lejupielādē katru attēlu tajā pašā mapē, kurā ir jūsu projekts. Parādiet attēlu lejupielādes laiku, no sākuma laika atņemot beigu laiku.

sākuma_laiks = laiks.perf_skaitītājs()
priekš img_url iekšā img_urls:
img_baiti = pieprasījumi.get (img_url).content
img_name = img_url.split('/')[3]
img_name = f'{img_name}.jpg'
ar atvērt (img_name, 'wb') img_file:
img_file.write (img_baiti)
drukāt (f'{img_name} tika lejupielādēts...')
finiša_laiks = laiks.perf_skaitītājs()
drukāt (f'Pabeigts {finish_time - start_time} sekundes')

Programma aizņem apmēram 22 sekundes, lai lejupielādētu 12 attēlus. Tas var atšķirties, jo attēlu lejupielādes laiks ir atkarīgs arī no interneta ātruma.

Modificējiet programmu, lai izmantotu vītņošanu, izmantojot moduli concurrent.features. Cilpas vietā izmantojiet funkciju. Šī ir funkcija, kuru pārsūtīsiet uz izpildītājs piemēram.

imports pieprasījumus
imports laiks
imports vienlaikus.nākotnes

img_urls = [
' https://images.unsplash.com/photo-1524429656589-6633a470097c',
' https://images.unsplash.com/photo-1530224264768-7ff8c1789d79',
' https://images.unsplash.com/photo-1564135624576-c5c88640f235',
' https://images.unsplash.com/photo-1541698444083-023c97d3f4b6',
' https://images.unsplash.com/photo-1522364723953-452d3431c267',
' https://images.unsplash.com/photo-1513938709626-033611b8cc03',
' https://images.unsplash.com/photo-1507143550189-fed454f93097',
' https://images.unsplash.com/photo-1493976040374-85c8e12f0c0e',
' https://images.unsplash.com/photo-1504198453319-5ce911bafcde',
' https://images.unsplash.com/photo-1530122037265-a5f1f91d3b99',
' https://images.unsplash.com/photo-1516972810927-80185027ca84',
' https://images.unsplash.com/photo-1550439062-609e1531270e',
]

sākuma_laiks = laiks.perf_skaitītājs()

defdownload_image(img_url):
img_baiti = pieprasījumi.get (img_url).content
img_name = img_url.split('/')[3]
img_name = f'{img_name}.jpg'
ar atvērt (img_name, 'wb') img_file:
img_file.write (img_baiti)
drukāt (f'{img_name} tika lejupielādēts...')

ar vienlaikus.nākotnes. ThreadPoolExecutor() izpildītājs:
executor.map (download_image, img_urls)

finiša_laiks = laiks.perf_skaitītājs()

drukāt (f'Pabeigts {finish_time-start_time} sekundes')

Pēc vītņu ieviešanas. Laiks ievērojami samazinās. Lai pabeigtu programmas izpildi, bija nepieciešamas tikai 4 sekundes.

Vītņošanai piemēroti scenāriji

Daži no vītņošanai piemērotajiem scenārijiem ir:

  • I/O saistītie uzdevumi: ja programma lielāko daļu laika pavada, gaidot ievades vai izvades darbību pabeigšanu. Vītņošana var uzlabot veiktspēju, ļaujot izpildīt citus uzdevumus, gaidot I/O darbību pabeigšanu.
  • Tīmekļa skrāpēšana: Tīmekļa skrāpēšana ietver HTTP pieprasījumu veikšanu un HTML atbilžu parsēšanu. Vītņu veidošana palīdz paātrināt procesu, ļaujot vienlaikus veikt vairākus pieprasījumus.
  • Uzdevumi, kas saistīti ar CPU: Pavediens var palīdzēt uzlabot veiktspēju, ļaujot paralēli izpildīt vairākus uzdevumus.

Iepazīstieties ar pavedieniem citās valodās

Python nav vienīgā valoda, kas atbalsta pavedienu veidošanu. Lielākā daļa programmēšanas valodu atbalsta kādu pavedienu veidošanu. Ir svarīgi iepazīties ar pavedienu ieviešanu citās valodās. Tādējādi jūs iegūstat nepieciešamās prasmes, lai risinātu dažādus scenārijus, kuros var tikt izmantota vītņošana.