向列表ll追加图片名称耗时极长,请求排查代码问题原因
解决列表存入耗时过长的问题
嘿,我来帮你揪出这个性能问题的根源!从你描述的情况来看,打印匹配图片正常但存入列表极慢,大概率是你的代码里存在重复的低效操作,最常见的就是下面这几种情况:
1. 循环内重复扫描目录(最可能的原因)
如果你是在遍历src列表的每一项时,都重新扫描一遍PulledImages目录来做匹配,那次数多了绝对会拖慢速度。举个例子,假设你写了类似这样的代码:
src = ["path/to/img1.jpg", "path/to/img2.png", ...] ll = [] for img_path in src: # 每次循环都重新遍历整个PulledImages目录,太浪费了! for pulled_img in os.listdir("PulledImages"): if pulled_img == os.path.basename(img_path): ll.append(pulled_img) print(pulled_img)
这种写法的问题在于,src里每有一个元素,你就把整个目录扫一遍——如果src有1000个元素,目录里有500张图,那就是50万次循环,能不慢吗?
优化方案:先缓存目录文件名到集合
集合的成员查询是O(1)常数时间,先一次性把PulledImages里的所有文件名存到集合里,之后直接做匹配就行:
import os src = ["path/to/img1.jpg", "path/to/img2.png", ...] # 一次性扫描目录,把文件名存进集合 pulled_names = set(os.listdir("PulledImages")) ll = [] for img_path in src: img_name = os.path.basename(img_path) if img_name in pulled_names: ll.append(img_name) print(img_name)
这样不管src有多少元素,目录只扫一次,匹配速度直接起飞。
2. 用低效的方式添加列表元素
如果你是用ll = ll + [img_name]这种方式拼接列表,而不是ll.append(img_name),那数据量大的时候也会特别慢。因为+拼接会创建一个新列表,每次都要复制原列表的所有元素;而append是直接在原列表末尾添加,效率高得多。
3. 循环内重复做IO操作
比如你每次匹配时都用os.path.exists()去检查文件是否存在,这也是磁盘IO操作,次数多了会拖慢速度。换成上面的集合缓存方式,就能避免重复IO。
快速排查步骤
- 先看代码里有没有把
os.listdir()、os.scandir()这类目录扫描操作放在循环内部 - 检查列表添加元素的方式是不是用了
+拼接,换成append - 把需要重复匹配的内容(比如目录文件名)提前缓存成集合,避免线性遍历
按照这个思路改,应该就能解决耗时过长的问题啦!
内容的提问来源于stack exchange,提问作者TheTank
相关产品推荐
相关产品推荐

