Heim > Artikel > Backend-Entwicklung > Effizienzvergleichsexperiment von Single-Thread, Multi-Thread und Multi-Prozess in Python
Vergleichsexperimente
Daten zeigen, dass Multithreading die Effizienz nicht wesentlich verbessert, wenn der Multithread-Prozess CPU-intensiv ist. Im Gegenteil, die Effizienz kann aufgrund des häufigen Threadwechsels abnehmen . Es wird empfohlen, einen Multiprozess zu verwenden. Wenn er IO-intensiv ist, kann der Multithread-Prozess die Leerlaufzeit nutzen, während er auf die IO-Blockierung wartet, um andere Threads auszuführen, um die Effizienz zu verbessern. Deshalb vergleichen wir die Effizienz verschiedener Szenarien anhand von Experimenten
(1) Stellen Sie die erforderlichen Module vor
import requests import time from threading import Thread from multiprocessing import Process
(2) Definieren Sie CPU-intensives Computing Funktionen
def count(x, y): # 使程序完成150万计算 c = 0 while c < 500000: c += 1 x += x y += y
(3) E/A-intensive Funktionen zum Lesen und Schreiben von Dateien definieren
def write(): f = open("test.txt", "w") for x in range(5000000): f.write("testwrite\n") f.close() def read(): f = open("test.txt", "r") lines = f.readlines() f.close()
(4) Netzwerkanforderungsfunktionen definieren
_head = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36'} url = "http://www.tieba.com" def http_request(): try: webPage = requests.get(url, headers=_head) html = webPage.text return {"context": html} except Exception as e: return {"error": e}
(5) Testlinearität Erforderliche Zeit zum Ausführen von E/A-intensiven Vorgängen, CPU-intensiven Vorgängen und Netzwerkanforderungsintensiven Vorgängen
# CPU密集操作 t = time.time() for x in range(10): count(1, 1) print("Line cpu", time.time() - t) # IO密集操作 t = time.time() for x in range(10): write() read() print("Line IO", time.time() - t) # 网络请求密集型操作 t = time.time() for x in range(10): http_request() print("Line Http Request", time.time() - t)
Ausgabe
CPU-intensiv: 95,6059999466, 91,57099986076355 92,52800011634827, 99,967999935 15015
IO intensiv: 24.25, 21.76699995994568, 21.769999980926514, 22.060999870300293
Netzwerkanfrage intensiv: 4.519999980926514, 8.5639998912 81128, 4.37 1000051498413, 4.522000074386597, 14.671000003814697
(6) Erforderlich, um Multithread-Parallelität zu testen Zeit für die Ausführung CPU-intensiver Vorgänge
counts = [] t = time.time() for x in range(10): thread = Thread(target=count, args=(1,1)) counts.append(thread) thread.start() e = counts.__len__() while True: for th in counts: if not th.is_alive(): e -= 1 if e <= 0: break print(time.time() - t)
Ausgabe: 99.9240000248, 101.26400017738342, 102.32200002670288
(7) Testen Sie die Zeit, die für die gleichzeitige Ausführung von E/A-intensiven Vorgängen mit mehreren Threads erforderlich ist
def io(): write() read() t = time.time() ios = [] t = time.time() for x in range(10): thread = Thread(target=count, args=(1,1)) ios.append(thread) thread.start() e = ios.__len__() while True: for th in ios: if not th.is_alive(): e -= 1 if e <= 0: break print(time.time() - t)
Ausgabe: 25.69700002670288, 24.02400016784668
(8) Testen Sie die Zeit, die für die gleichzeitige Ausführung netzwerkintensiver Vorgänge mit mehreren Threads erforderlich ist
t = time.time() ios = [] t = time.time() for x in range(10): thread = Thread(target=http_request) ios.append(thread) thread.start() e = ios.__len__() while True: for th in ios: if not th.is_alive(): e -= 1 if e <= 0: break print("Thread Http Request", time.time() - t)
Ausgabe: 0.7419998645782471, 0,3839998245239258, 0,390001049041748 Testen der gleichzeitigen Ausführung von E/A-intensiven Vorgängen durch mehrere Prozesse
Ausgabe: 12.509000062942505, 13.059000015258789counts = [] t = time.time() for x in range(10): process = Process(target=count, args=(1,1)) counts.append(process) process.start() e = counts.__len__() while True: for th in counts: if not th.is_alive(): e -= 1 if e <= 0: break print("Multiprocess cpu", time.time() - t)
(11) Testen mehrerer Prozesse zur gleichzeitigen Ausführung HTTP-anforderungsintensiver Vorgänge
Ausgabe: 0,5329999923706055, 0,476000070571 8994t = time.time() ios = [] t = time.time() for x in range(10): process = Process(target=io) ios.append(process) process.start() e = ios.__len__() while True: for th in ios: if not th.is_alive(): e -= 1 if e <= 0: break print("Multiprocess IO", time.time() - t)
Experimentelle Ergebnisse
t = time.time() httprs = [] t = time.time() for x in range(10): process = Process(target=http_request) ios.append(process) process.start() e = httprs.__len__() while True: for th in httprs: if not th.is_alive(): e -= 1 if e <= 0: break print("Multiprocess Http Request", time.time() - t)
Anhand der obigen Ergebnisse können wir sehen:
Multi-Threading funktioniert nicht Bei IO-intensiven Vorgängen scheint es einen großen Vorteil zu geben (vielleicht ist die IO-Operationsaufgabe schwerer, was die Vorteile widerspiegeln kann). Die lineare Ausführungsleistung eines einzelnen Threads ist offensichtlich schlechter als die eines einzelnen Threads bei CPU-intensiven Vorgängen, jedoch für Vorgänge B. Netzwerkanforderungen, die darauf warten, Threads zu blockieren, sind die Vorteile von Multithreading sehr groß
Mehrere Prozesse können Leistungsvorteile bei CPU-intensiven, E/A-intensiven und Netzwerkanforderungsintensiven Vorgängen aufweisen (threadblockierende Vorgänge treten häufig auf). Für netzwerkanforderungsintensive Vorgänge ist es jedoch fast dasselbe wie Multithreading, beansprucht jedoch mehr Ressourcen wie CPU. In diesem Fall können wir also Multithreading für die Ausführung auswählen