1 eventlet性能探究
测试代码如下:
# -*- encoding: utf-8 -*-
from datetime import datetime
import time
import eventlet
eventlet.monkey_patch()
# eventlet.monkey_patch(all=False,
# os=True,
# select=True,
# socket=True,
# thread=False,
# time=True)
def timeHelper(func):
def wrapper(*args, **kwargs):
try:
start = datetime.now()
info = "############ function: {func} Begin , start: {start} ##########" .format(
func=func.__name__,
start=str(start))
print info
result = func(*args, **kwargs)
end = datetime.now()
diff = end - start
info = "##### function: {func} End , end: {end}, cost time: {cost} #####" .format(
func=func.__name__,
end=str(end),
cost=str(diff))
print info
return result
except Exception as ex:
info = "Exception type is %s, message is %s" % (ex.__class__.__name__, ex)
print info
return wrapper
def func1():
time.sleep(3)
info = "func1 time: {curTime}".format(
curTime=datetime.now()
)
print info
def func2():
time.sleep(3)
info = "func2 time: {curTime}".format(
curTime=datetime.now()
)
print info
@timeHelper
def useEventlet():
pool = eventlet.GreenPool()
pool.spawn(func1)
pool.spawn(func2)
pool.waitall()
@timeHelper
def notUseEventlet():
func1()
func2()
def process():
notUseEventlet()
useEventlet()
if __name__ == "__main__":
process()
分析:
这里用sleep方法来模拟I/O密集型任务
2 实验结果
未使用eventlet的执行结果:
############ function: notUseEventlet Begin , start: 2019-09-18 15:53:28.481971 ##########
func1 time: 2019-09-18 15:53:31.485827
func2 time: 2019-09-18 15:53:34.487574
##### function: notUseEventlet End , end: 2019-09-18 15:53:34.487858, cost time: 0:00:06.005887 #####
使用eventlet.monkey_patch()的执行结果:
############ function: useEventlet Begin , start: 2019-09-18 15:54:01.934679 ##########
func1 time: 2019-09-18 15:54:04.938762
func2 time: 2019-09-18 15:54:04.939150
##### function: useEventlet End , end: 2019-09-18 15:54:04.939206, cost time: 0:00:03.004527 #####
使用
eventlet.monkey_patch(all=False,
os=True,
select=True,
socket=True,
thread=False,
time=True)
的执行结果:
############ function: useEventlet Begin , start: 2019-09-18 15:56:29.513413 ##########
func1 time: 2019-09-18 15:56:32.515038
func2 time: 2019-09-18 15:56:32.515170
##### function: useEventlet End , end: 2019-09-18 15:56:32.515231, cost time: 0:00:03.001818 #####
3 结论
3.1 使用eventlet可以通过相互渡让cpu来实现并发,不使用eventlet,则程序变成串行并且性能较差。
3.2 使用
eventlet.monkey_patch()
和
eventlet.monkey_patch(all=False,
os=True,
select=True,
socket=True,
thread=False,
time=True)
在性能上一般没有区别。
4 python性能优化
如果在某个方法中同时调用多个api,并且没有使用eventlet,则该方法中每个api串行执行,
性能较差。
建议使用eventlet.GreenPool来对多个api并发执行来提升性能。
代码样例如下:
import eventlet
eventlet.monkey_patch()
def useEventlet():
pool = eventlet.GreenPool()
pool.spawn(func1, arg1)
pool.spawn(func2, arg2)
pool.waitall()
其中可以设置arg1为结果参数,即初始化arg1是空的,
然后在func1中将执行的结果赋值给arg1,这样就解决了eventlet.GreenPool.spawn无返回值的问题。
参考:
https://www.cnblogs.com/Security-Darren/p/4168233.html
https://wenku.baidu.com/view/e695e811fe4733687e21aaed.html
https://blog.csdn.net/hzrandd/article/details/11815323