• python函数运行加速


    前言:

    博主在处理一个任务的时候,需要需要遍历一个文件夹下面所有的文件,但是单个文件的处理特别耗时,发现cp几乎在单核工作,根本没有发挥计算机的性能,下面来看一下具体的操作,调用所有的核心一起工作。

    基本原理可参看这篇Python GIL锁_两只蜡笔的小新的博客-CSDN博客

    一、代码改动前的被调用函数:

    为了能够将使用方法讲清楚,下面详细说明函数改造前后的对比。

    1. def batch_process(imgdir, savedir_d1, savedir_d3):
    2. for i in tqdm(os.listdir(imgdir)):
    3. if i.split('.')[-1] != 'png':
    4. # print('continue..')
    5. continue
    6. direction_process_d1(os.path.join(imgdir, i), savedir_d1)
    7. direction_process_d3(os.path.join(imgdir, i), savedir_d3)
    1. start = time.time()
    2. ## connectivity cube
    3. batch_process(gt_path, connect_d1_path, connect_d3_path)
    4. end = time.time()
    5. print('Finished Creating connectivity cube, time {0}s'.format(end - start))

    运行界面截图

     然后可以看出cpu的核心使用情况,有两个核心上下跳动,说明两个核心在工作但不是同时工作。

    二、代码改动后:

    函数改造:

    1. def batch_process(imgdir, savedir_d1, savedir_d3,range_list=[0,None]):
    2. for i in tqdm(os.listdir(imgdir)[range_list[0]:range_list[-1]]):
    3. if i.split('.')[-1] != 'png':
    4. # print('continue..')
    5. continue
    6. direction_process_d1(os.path.join(imgdir, i), savedir_d1)
    7. direction_process_d3(os.path.join(imgdir, i), savedir_d3)

    改造原理,可以看出我在函数的出入参数位置加了一个 range_list=[0,None],

    并将for循环遍历的语句:

    for i in tqdm(os.listdir(imgdir)):-》改为

    for i in tqdm(os.listdir(imgdir)[range_list[0]:range_list[-1]]):

    可以检查函数的功能,在不传入任何参数的情况下,该函数的功能保持和原函数一致。

    而这个range_list的具体作用应该很明显,用于控制函数操作的文件夹下面的文件的范围

    正是这个可以控制的范围让这个函数在稍后可以并行运行

    主函数改造:

    1. start = time.time()
    2. ## connectivity cube
    3. import multiprocessing
    4. from functools import partial
    5. BUCKET_NUM = 8 #并行线程数量
    6. #### 生成 range_list ###################################
    7. BUCKET_SIZE = int(len(os.listdir(gt_path)) / BUCKET_NUM)
    8. range_list =[]
    9. for x in range(BUCKET_NUM):
    10. end_f = True if len(os.listdir(gt_path))%BUCKET_NUM==0 else False
    11. range_list.append([x*BUCKET_SIZE,(x+1)*BUCKET_SIZE])
    12. range_list.append([(x + 1) * BUCKET_SIZE,None]) if end_f else ''
    13. ##### finish ###########################################
    14. pool = multiprocessing.Pool()# 构造多线程池
    15. func = partial(batch_process, gt_path, connect_d1_path, connect_d3_path)#包装函数
    16. pool.map(func, range_list) #传入可变参数
    17. pool.close()
    18. pool.join()
    19. # batch_process(gt_path, connect_d1_path, connect_d3_path)
    20. end = time.time()
    21. print('Finished Creating connectivity cube, time {0}s'.format(end - start))

    函数运行过程截图:这里只展示了一个进程,等待运行结束就会显示所有的进程。

     运行结束截图:

    之前的1h的代码,下载只需要9分30秒 ,再来看看CPU的使用情况:

  • 相关阅读:
    以MapBox为核心构建Vue地图组件库教程
    iNFTnews | 佳能推出“佳能传奇”计划以支持摄影NFT事业
    “带薪划水”偷刷阿里老哥的面经宝典,三次挑战字节,终成正果
    非零基础自学Java (老师:韩顺平) 第3章 变量 3.5 程序中 + 号的使用 && 3.6 数据类型 && 3.7 整数类型 && 3.8 浮点类型
    方法练习(二)
    从0到0.01入门React | 008.精选 React 面试题
    新概念英语第二册(88)
    ABB机器人RWS连接方法
    LSF-bsub命令
    读《遇见未知的自己》笔记
  • 原文地址:https://blog.csdn.net/weixin_44503976/article/details/126764308