python - 为什么 os.scandir() 变慢/如何重新组织巨大的目录?
问题描述
我有一个目录,其中包含 300 万多个文件(我应该首先避免创建)。使用 os.scandir() 简单地打印出名称,
for f in os.scandir():
print(f)
对于前 200,000 个文件,每个项目需要 0.004 秒,但会大幅减慢到每个项目 0.3 秒。再次尝试时,它做了同样的事情——前约 200,000 人快速,然后慢下来。
在等待一个小时并再次运行后,这一次对于前 400,000 个文件来说速度很快,但随后以同样的方式变慢了。
这些文件都从 1908 年到 1963 年之间的一年开始,所以我尝试使用 bash 命令重新组织文件,例如
for i in {1908..1963}; do
> mkdir ../test-folders/$i;
> mv $i* ../test-folders/$i/;
> done
但它最终被挂断,永远无法到达任何地方......
关于如何重新组织这个巨大的文件夹或更有效地列出目录中的文件的任何建议?
解决方案
钱币。那是很多文件。我不确定为什么 python 开始变慢,这很有趣。但是你遇到问题的原因有很多。一,目录可以被认为是一种特殊类型的文件,它只保存其中所有文件的文件名/数据指针(非常简化)。当操作系统在内存中缓存一些信息以加速整个系统的磁盘访问时,它可以更快地访问任何文件。
python变得更慢似乎很奇怪,也许你正在使用python中的内部存储器或其他一些机制。
但是,让我们解决问题的根源。您的 bash 脚本存在问题,因为每次使用*
字符时,您都在强制 bash 脚本读取整个目录(并且可能按字母顺序对其进行排序)。获取列表一次然后对列表的各个部分进行操作可能更明智。也许是这样的:
/bin/ls -1 > /tmp/allfiles
for i in {1908..1963}; do
echo "moving files starting with $i"
mkdir ../test-folders/$i
mv $(egrep "^$i" /tmp/allfiles) ../test-folders/$i/
done
这只会读取一次目录(有点),并会告诉您它的速度有多快。
推荐阅读
- oracle11g - 检查数据库中用户的存在
- ruby-on-rails - 在 Ruby Gem 中描述脚本依赖关系的最佳方式 - 我应该在哪里需要?
- .net - 角度事件问题:每次我选择菜单栏时它总是同时选择
- google-cloud-shell - 如何在 Cloud Shell 上获得更多磁盘空间?
- bash - Bash 或 cmd 将 Java 标准附加到文本文件中
- javascript - 如何使用隐藏的输入框进行输入?
- python - 如何将用户输入的常量(pi,e)转换为 python 中的浮点数?
- sql - 如何删除/替换 Oracle 结果集中的“sys.DBMSOUTPUT_LINESARRAY”?
- python - Tensorflow / Keras教程保存/加载模型不起作用
- sql - 如何在 sql 中的 datetime2 类型中有两个日期变量?