当我们对大批量的文件进行操作时,经常会用到for循环,如果数据量为10万以上的图片数据,正常的单线程操作会非常慢,比如下面的简单的图片复制操作,把A路径下的图片复制到B路径下,运行后,耗时很多
# -*- coding: utf-8 -*-
import time
import shutil
import os
import tqdm
import time
from loguru import logger
srcDir="/home/ff/dataset/cat"
dstDir="/home/ff/dataset/test_multithread"
def copy_file(src_dir, dst_dir):
files = os.listdir(src_dir)
for file in tqdm.tqdm(files):
file_path = os.path.join(src_dir, file)
dst_file_path= os.path.join(dst_dir,file)
time.sleep(0.02)
shutil.copy(file_path,dst_file_path)
t0=time.time()
copy_file(srcDir,dstDir)
t1=time.time()
logger.info(f"time is:{t1-t0}")
现在我们用多线程进行尝试,我感觉多线程操作有点繁琐,尤其对于那些频繁且不通用的文件操作,下面我用multiporcessing来实现多线程,看这个应用你比如把循环的变量提前得到才可以用。
# -*- coding: utf-8 -*-
import time
import shutil
import os
import time
from loguru import logger
from multiprocessing.dummy import Pool as ThreadPool
srcDir="/home/ff/dataset/cat"
dstDir="/home/ff/dataset/test_multithread"
files = os.listdir(srcDir)
def copy_file(file):
file_path = os.path.join(srcDir, file)
dst_file_path = os.path.join(dstDir, file)
time.sleep(0.02)
shutil.copy(file_path, dst_file_path)
os.mkdirs (dstDir) if not os.path.exists(dstDir) else False
pool = ThreadPool()
t_start =time.time()
pool.map(copy_file, files)
t_end =time.time()
logger.info(f"time is :{t_end-t_start}")
pool.close()
pool.join()
结果比较:
第一个没加多线程的代码耗时大概为95s,??加了多线程的代码耗时大概6s, 大概速度提高了16倍
另一种写法,其他保持不变, 可以控制线程数,这样感觉更灵活
import multiprocessing
#todo
p=multiprocessing.Pool(16)
t_start =time.time()
p.map(copy_file, files)
t_end =time.time()
logger.info(f"time is :{t_end-t_start}")
p.close()
p.join()
|