python3下多线程和协程性能的简单测试

2018-12-06  本文已影响0人  Xpitz

欢迎关注我的微信公众号:「阿拉平平」

这几天初步学习了python3下高并发编程,简单测试并记录下。
由于本次是针对I/O密集操作的测试,所以也就选择了多线程和协程来做对比。python版本为3.6.5。

多线程:

测试脚本

from threading import Thread
import time


def io_func():
    # 模拟io等待时间,设置3秒
    time.sleep(3)


if __name__ == '__main__':
    count = 100
    start_time = time.time()    
    threads = [Thread(target=io_func) for i in range(count)]
    [threads[i].start() for i in range(count)]
    [threads[i].join() for i in range(count)]
    end_time = time.time()
    print(end_time - start_time)

执行结果

count 三次平均时间(秒)
100 3.014s
1000 3.083s
10000 3.848s
100000 13.574s

协程

测试脚本

from gevent import monkey
monkey.patch_all()
import gevent
import time


def temp_test():
    time.sleep(3)


if __name__ == '__main__':
    count = 100
    start_time = time.time()
    gevent.joinall([gevent.spawn(temp_test) for i in range(count)])
    end_time = time.time()
    print(end_time - start_time)

执行结果

count 三次平均时间(秒)
100 3.008s
1000 3.521s
10000 6.587s
100000 14.634s

从执行结果来看:
记录数在100-1000时,两者用时并没有明显差别。
记录数在1000-10000时,线程执行效率更占优势。

那假设数据量在1000,000的情况下,两者的性能情况又是怎样的?
在百万并发的情况下,原先的多线程脚本可能会hold不住,所以要改写下。

from concurrent.futures import ThreadPoolExecutor
import time


def io_func():    
    time.sleep(3)


if __name__ == '__main__':
    count = 1000000
    start_time = time.time()
    # 加入线程池,设置并发50000
    with ThreadPoolExecutor(50000) as executor:
        for i in range(count):
            executor.submit(io_func)    
    end_time = time.time()
    print(end_time - start_time)

加入线程池后,脚本可以正常运行,但结果浮动很大。执行结果在4~7分钟。期间本地主机cpu使用率占满,内存也在95%以上。

反观协程,本地主机cpu和内存略微上升。测试三次,执行结果均在3分钟以内。在百万并发情况下,协程无论在执行效率还是占用资源方面相比多线程都更具优势。


写在后面:

测试脚本也比较简单,次数也有限,所以结果可能比较片面。主要是为了加深自己对python下高并发编程的理解。如有不足的地方,也希望能够给予指正。

上一篇 下一篇

猜你喜欢

热点阅读