我正在尝试使用多线程和/或多处理来加快我的脚本的速度。本质上,我有一个从CSV读取的10,000个子网的列表,我希望将其转换为IPv4对象,然后存储在数组中。
我的基本代码如下,并在大约300毫秒内执行:
aclsConverted = []
def convertToIP(ip):
aclsConverted.append(ipaddress.ip_network(ip))
for y in acls:
convertToIP(y['srcSubnet'])
如果我尝试使用current.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'])
然后,如果我尝试使用current.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'])
我在其上运行该服务器的服务器具有28个物理核心。
将很高兴收到关于我可能做错事情的任何建议!
如果任务很小,那么管理多处理/多线程的开销比并行运行任务的开销要昂贵得多。
您可以尝试遵循。
仅创建到进程(非线程!),一个处理前5000个子网,另一个处理其他5000个子网。
您应该可以看到一些性能改进。
另一方面,Python中的多线程将对没有IO和纯Python代码的任务具有根本没有性能改进。
原因是臭名昭著的GIL(全局解释器锁)。在python中,您永远无法在同一进程中并行执行两个python字节代码。
Python中的多线程对于具有IO(执行网络访问,执行睡眠,调用模块,用C实现并释放GIL的任务仍然有意义)
线程模块用于IN / OUT操作,它绝对无法加速将字符串转换为ip地址实例。当您创建线程时,您会花时间在它们上,但是却得不到任何好处,这就是为什么没有线程的程序更快的原因。