一.使用np.vectorize
例子:
import numpy as np
def myfunc(a, b):
if a>b:
return a-b
else:
return a+b
vfunc = np.vectorize(myfunc)
t0=time.time()
vfunc(np.random.randint(5,size=10000000), 2)
t1=time.time()
print('speed_times:'+str(t1-t0))
#speed_times:3.2735631465911865
t0=time.time()
[myfunc(data, 2) for data in np.random.randint(5,size=10000000)]
t1=time.time()
print('speed_times:'+str(t1-t0))
#speed_times:7.929015398025513
优点:
并行执行快
缺点:
输出要求严格,这里myfunc只能返回一个值,如果是list,dict类型就不行了
二.使用ProcessPoolExecutor
在concurrent.futures 库中有ThreadPoolExecutor(多线程),ProcessPoolExecutor(多进程)
ThreadPoolExecutor,ProcessPoolExecutor的区别:
ThreadPoolExecutor:
ThreadPoolExecutor多线程并行执行任务,可以共享当前进程变量,但缺点也很致命,由于python GIL(Global Interpreter Lock 全局解释器锁)
的原因,及时多线程,但其实仍然最多只能占用CPU一个核,准确只能说是并发了,如果指定的任务和线程数不恰当(比如一个任务很短,线程数量很多,导致线程频繁调用回收),那么效率还不如单线程
ProcessPoolExecutor:
ProcessPoolExecutor可以使用多核进行计算,但缺点就是进程之间共享数据就比较麻烦,消耗更多的内存。
例子:
注意ProcessPoolExecutor使用的位置,否则会造成多进程循环调用,会报
concurrent.futures.process.BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending错误。
from concurrent.futures import ProcessPoolExecutor
URLS = ['http://www.baidu.com', 'http://qq.com', 'http://sina.com']
def task(url, index,timeout=10):
return index,url
#在此例子中if __name__ == "__main__":一定要加,因为没有if __name__会在创建子进程的时候又会运行,导致错误
if __name__ == "__main__":
p = ProcessPoolExecutor(max_workers=3)
results = p.map(task, URLS,range(3))
p.shutdown(wait=True)
for ret,url in results:
print(ret,url)