And*_*ris 6 python multithreading concurrent.futures
我正在尝试使用多线程和/或多处理来加速我的脚本。本质上,我有一个从 CSV 读取的 10,000 个子网列表,我想将其转换为 IPv4 对象,然后存储在数组中。
我的基本代码如下,执行时间大约为 300 毫秒:
aclsConverted = []
def convertToIP(ip):
aclsConverted.append(ipaddress.ip_network(ip))
for y in acls:
convertToIP(y['srcSubnet'])
Run Code Online (Sandbox Code Playgroud)
如果我尝试使用并发.futures 线程,它可以工作,但速度慢 3-4 倍,如下所示:
aclsConverted = []
def convertToIP(ip):
aclsConverted.append(ipaddress.ip_network(ip))
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
for y in acls:
executor.submit(convertToIP,y['srcSubnet'])
Run Code Online (Sandbox Code Playgroud)
然后,如果我尝试使用并发。futures 处理速度会慢 10-15 倍,并且数组为空。代码如下
aclsConverted = []
def convertToIP(ip):
aclsConverted.append(ipaddress.ip_network(ip))
with concurrent.futures.ProcessPoolExecutor(max_workers=20) as executor:
for y in acls:
executor.submit(convertToIP,y['srcSubnet'])
Run Code Online (Sandbox Code Playgroud)
我运行它的服务器有 28 个物理核心。
任何关于我可能做错的事情的建议将不胜感激!
如果任务太小,那么管理多处理/多线程的开销通常比并行运行任务的好处更昂贵。
您可以尝试以下操作:
只是创建两个进程(不是线程!!!),一个处理前 5000 个子网,另一个处理其他 5000 个子网。
在那里您可能会看到一些性能改进。但您执行的任务不是 CPU 或 IO 密集型的,因此不确定它是否有效。
另一方面,Python 中的多线程对于没有 IO 并且是纯 Python 代码的任务来说根本没有任何性能改进。
原因就是臭名昭著的GIL(全局解释器锁)。在 python 中,你永远不能在同一进程中并行执行两个 python 字节代码。
python 中的多线程对于具有 IO(执行网络访问)、执行睡眠、调用模块、用 C 实现并释放 GIL 的任务仍然有意义。例如,numpy 释放了 GIL,因此是多线程的良好候选者