Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 由于页面缓存,os.walk()在第一次运行后是否会更快?_Python_Caching - Fatal编程技术网

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将元数据视为另一个文件,因此在读取这些文件时使用相同的缓存;然后将数据映射用于主记录和偏移,以查找这些文件或类似策略。