• Python中单线程、多线程和多进程的效率对比实验


    GIL机制导致如下结果:

    Python的多线程程序并不能利用多核CPU的优势 (比如一个使用了多个线程的计算密集型程序只会在一个单CPU上面运行)
    python多线程适合io操作密集型的任务(如socket server 网络并发这一类的)
    python多线程不适合cpu密集操作型的任务,主要使用cpu来计算,如大量的数学计算。
    那么如果有cpu密集型的任务怎么办,可以通过多进程来操作(不是多线程)。
    假如CPU有8核,每核CPU都可以用1个进程,每个进程可以用1个线程来进行计算。

     1、线性模式测试

     1 import requests
     2 import time
     3 from threading import Thread
     4 from multiprocessing import Process
     5 
     6 #定义CPU密集的计算函数
     7 def count(x, y):
     8     # 使程序完成150万计算
     9     c = 0
    10     while c < 500000:
    11         c += 1
    12         x += x
    13         y += y
    14 
    15 #定义IO密集的文件读写函数
    16 def write():
    17     f = open("test.txt", "w")
    18     for x in range(5000000):
    19         f.write("testwrite
    ")
    20     f.close()
    21 
    22 def read():
    23     f = open("test.txt", "r")
    24     lines = f.readlines()
    25     f.close()
    26 
    27 def io():
    28     write()
    29     read()
    30 
    31 #定义网络请求函数
    32 _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'}
    33 url = "http://www.tieba.com"
    34 def http_request():
    35     try:
    36         webPage = requests.get(url, headers=_head)
    37         html = webPage.text
    38         return {"context": html}
    39     except Exception as e:
    40         return {"error": e}
    41 
    42 #---------------------------------------
    43 #CPU密集操作
    44 t = time.time()
    45 for x in range(10):
    46     count(1, 1)
    47 print("Line cpu", time.time() - t)
    48 
    49 # IO密集操作
    50 t = time.time()
    51 for x in range(10):
    52     io()
    53 print("Line IO", time.time() - t)
    54 
    55 # 网络请求密集型操作
    56 t = time.time()
    57 for x in range(10):
    58     http_request()
    59 print("Line Http Request", time.time() - t)

     --运行---------------------结果:
     ('Line cpu', 97.26900005340576)
     ('Line IO', 24.319000005722046)
     ('Line Http Request', 209.94899988174438)


    2、线程模式测试
     1 #定于线程公共函数
     2 def mythread(fun,*args):
     3     counts = []
     4     for x in range(10):
     5         thread = Thread(target=fun, args=args)
     6         counts.append(thread)
     7         thread.start()
     8     e = counts.__len__()
     9     while True:
    10         for th in counts:
    11             if not th.is_alive():
    12                 e -= 1
    13         if e <= 0:
    14             break
    15 
    16 #测试多线程并发执行CPU密集操作所需时间
    17 t = time.time()
    18 mythread(count,1,1)
    19 print("thread cpu ",time.time() - t)
    20 
    21 #测试多线程并发执行IO密集操作所需时间
    22 t = time.time()
    23 mythread(io)
    24 print("thread IO ",time.time() - t)
    25 
    26 #测试多线程并发执行网络密集操作所需时间
    27 t = time.time()
    28 mythread(http_request)
    29 print("Thread Http Request", time.time() - t)

    --运行---------------------结果:

    ('thread cpu ', 102.20300006866455)
    ('thread IO ', 654.5730001926422)
    ('Thread Http Request', 21.170999765396118)

     3.进程模式测试

     1 def myprocess(fun,*args):
     2     counts = []
     3     for x in range(10):
     4         process = Process(target=fun,args=args)
     5         counts.append(process)
     6         process.start()
     7     e = counts.__len__()
     8     while True:
     9         for th in counts:
    10             if not th.is_alive():
    11                 e -= 1
    12         if e <= 0:
    13             break
    14 
    15 if __name__ == '__main__': #没这句会报错。
    16     #测试多进程并发执行CPU密集操作所需时间
    17     t = time.time()
    18     myprocess(count,1,1)
    19     print("Multiprocess cpu", time.time() - t)
    20 
    21     #测试多进程并发执行IO密集型操作
    22     t = time.time()
    23     myprocess(io)
    24     print("Multiprocess IO", time.time() - t)
    25 
    26     #测试多进程并发执行Http请求密集型操作
    27     t = time.time()
    28     myprocess(http_request)
    29     print("Multiprocess Http Request", time.time() - t)

    --运行---------------------结果:

    ('Multiprocess cpu', 20.168999910354614)
    ('Multiprocess IO', 11.82699990272522)
    ('Multiprocess Http Request', 21.805000066757202)

    实验结果

      CPU密集型操作 IO密集型操作 网络请求密集型操作
    单线程操作 97 24 310
    多线程操作 102 654 21
    多进程操作 20 12 22

    通过上面的结果,我们可以看到:

    • 多线程在IO密集型的操作下似乎也没有很大的优势,在CPU密集型的操作下明显地比单线程线性执行性能更差,但是对于网络请求这种忙等阻塞线程的操作,多线程的优势便非常显著了
    • 多进程无论是在CPU密集型还是IO密集型以及网络请求密集型(经常发生线程阻塞的操作)中,都能体现出性能的优势。不过在类似网络请求密集型的操作上,与多线程相差无几,但却更占用CPU等资源,所以对于这种情况下,我们可以选择多线程来执行

    一句话总结:cpu和io密集操作使用多进程,网络操作使用多线程   

  • 相关阅读:
    seaborn---样式控制/调色板
    matplotlib---插值画二维、三维图
    25.推荐---协同过滤(Collaborative Filtering)
    PageRank
    词向量---LSA(Latent Semantic Analysis)
    深入理解Java 8 Lambda
    理解java的 多态
    Java命名规范
    Java语言中几个常用的包
    java中的类、成员变量、方法的修饰符。
  • 原文地址:https://www.cnblogs.com/kevincaptain/p/10437247.html
Copyright © 2020-2023  润新知