Python 由于页面缓存,os.walk()在第一次运行后是否会更快?
我使用Python 由于页面缓存,os.walk()在第一次运行后是否会更快?,python,caching,Python,Caching,我使用os.walk来迭代,比如说,1000个文件(只是迭代,没有对这些文件进行任何处理)。 第一次运行速度很慢,但后续运行(在同一路径上)速度大约快20倍 据我所知,os.walk和os.listdir(由os.walk使用)没有进行任何缓存,也没有使用FindFirstFile/FindNextFile(在我的Windows平台上由os.listdir使用) 这是由于页面缓存还是其他原因 仅供参考,我正在尝试编写一个备份应用程序,需要处理大量文件。如果确实是由于页面缓存,那么我需要编写自己的
os.walk
来迭代,比如说,1000个文件(只是迭代,没有对这些文件进行任何处理)。
第一次运行速度很慢,但后续运行(在同一路径上)速度大约快20倍
据我所知,os.walk
和os.listdir
(由os.walk
使用)没有进行任何缓存,也没有使用FindFirstFile
/FindNextFile
(在我的Windows平台上由os.listdir
使用)
这是由于页面缓存还是其他原因
仅供参考,我正在尝试编写一个备份应用程序,需要处理大量文件。如果确实是由于页面缓存,那么我需要编写自己的缓存机制。您的操作系统在这里进行缓存;目录查找需要缓慢的磁盘访问,因此这种访问被大量缓存
例如,用于缓存文件系统元数据(如目录列表)的
ntfs.sys
驱动程序。我意识到您已经得到了问题的答案,但这让我对这种缓存在Linux中的工作方式感到好奇,所以我执行了一个小的基准测试
我创建了一个包含1000个子目录的目录,在每个子目录中我创建了1000个文件。总共1000个文件夹和100万个文件
seq 1000 | parallel "mkdir {} && seq 1000 | parallel touch {}/\{\}"
这应该会给os.walk提供一些可以使用的东西。接下来,我创建了一个测试脚本,它使用os.walk
递归地计算目录中的文件数:
def count_dir(path):
count = 0
for _, _, files in os.walk(path):
count += len(files)
return count
我运行了几次,平均执行时间为2.27秒
接下来,我再次运行了几次测试,但是在每次执行之间刷新了页面缓存,然后再次刷新了dentry/inode缓存,最后是同样的事情,但是刷新了上面所有的缓存
To free pagecache:
echo 1 > /proc/sys/vm/drop_caches
To free dentries and inodes:
echo 2 > /proc/sys/vm/drop_caches
To free pagecache, dentries and inodes:
echo 3 > /proc/sys/vm/drop_caches
结果是:
no flush page cache dentries/inodes all
mean 2.27 2.56 4.24 4.80
stdev 0.052 0.055 0.127 0.108
%RSD 2.27% 2.15% 2.99% 2.26%
median 2.26 2.54 4.21 4.78
iterations 27 27 31 10
基准测试在新SSD驱动器上的ext4
文件系统上运行。Linux版本是3.17.7
毫不奇怪,页面缓存以及dentries/inodes缓存对这个基准测试的结果影响很大。然而,我有点惊讶,仅仅刷新页面缓存会产生如此大的差异,因为应该可以一次读取这些文件的大部分文件系统元数据,但我可能遗漏了一些东西
我会说页面缓存并没有多大区别,因为包含文件系统元数据的页面的缓存未命中相对较少。但我的直觉似乎是错的。想知道为什么吗?是这种缓存吗?因为如果是,那么我将在重新启动后丢失缓存。@fans656:这是关于文件缓存的。这里是目录结构的缓存。@fans656:这是每个文件的缓存;但目录元数据也被缓存。这取决于缓存的文件系统驱动程序,我为您找到了
ntfs.sys
的参考。@fans656:也就是说,我怀疑ntfs将元数据视为另一个文件,因此在读取这些文件时使用相同的缓存;然后将数据映射用于主记录和偏移,以查找这些文件或类似策略。