使用Python处理许多文件
任务: 我正在处理存储在外部usb磁盘上的4 TB数据/文件:图像、html、视频、可执行文件等 我希望使用以下架构索引sqlite3数据库中的所有这些文件:使用Python处理许多文件,python,linux,file,sqlite,subprocess,Python,Linux,File,Sqlite,Subprocess,任务: 我正在处理存储在外部usb磁盘上的4 TB数据/文件:图像、html、视频、可执行文件等 我希望使用以下架构索引sqlite3数据库中的所有这些文件: path TEXT, mimetype TEXT, filetype TEXT, size INT 到目前为止: I os.walk递归地遍历装载的目录,使用python的子进程执行linuxfile命令,并使用os.path.getsize()获取大小。最后,结果被写入数据库,存储在我的计算机上——当然,usb是用-o ro安装的。顺
path TEXT, mimetype TEXT, filetype TEXT, size INT
到目前为止:
I os.walk递归地遍历装载的目录,使用python的子进程执行linuxfile
命令,并使用os.path.getsize()获取大小。最后,结果被写入数据库,存储在我的计算机上——当然,usb是用-o ro安装的。顺便说一下,不要穿线
你可以在这里看到完整的代码
问题:
代码真的很慢。我意识到direcory结构越深,代码越慢。我想,os.walk可能是个问题
问题:
os.walk
更快的替代方法
对。事实上,这是多重的
- (将在3.5中的stdlib中)的速度明显快于
walk
- C函数比scandir快得多。我很确定PyPI上有包装器,尽管我不知道如何推荐,而且通过
或ctypes
使用也不难,如果你知道Ccffi
- 该工具使用
,如果不能直接使用fts
,则始终可以将fts
添加到该工具中子流程
穿线会把事情搞定吗 这取决于我们没有的系统详细信息,但是……您将所有的时间都花在等待文件系统上。除非您有多个仅在用户级别绑定在一起的独立驱动器(也就是说,不是LVM或其下的某些东西,如RAID),或者根本没有(例如,一个驱动器只是安装在另一个文件系统下),否则并行发出多个请求可能不会加快速度 不过,这很容易测试;为什么不试试看呢
还有一个想法:您可能会花费大量时间来生成
文件
进程并与之通信。有多个Python库使用与之相同的代码。我不想特别推荐其中一种,所以这里有一些建议
正如monkut所建议的,确保您正在进行批量提交,而不是使用sqlite自动提交每个插入。同样,sqlite每秒可以进行50000次插入,但每秒只有几十次事务 当我们进行此操作时,如果您可以将sqlite文件放在与正在扫描的文件系统不同的文件系统上(或者将其保存在内存中,直到完成,然后一次性将其写入磁盘),那么可能值得一试
最后,但最重要的是:
- 分析代码以查看热点在哪里,而不是猜测
- 创建小型数据集,并对不同的备选方案进行基准测试,以了解您能获得多少好处
os.walk
更快的替代方法
对。事实上,这是多重的
- (将在3.5中的stdlib中)的速度明显快于
walk
- C函数比scandir快得多。我很确定PyPI上有包装器,尽管我不知道如何推荐,而且通过
或ctypes
使用也不难,如果你知道Ccffi
- 该工具使用
,如果不能直接使用fts
,则始终可以将fts
添加到该工具中子流程
穿线会把事情搞定吗 这取决于我们没有的系统详细信息,但是……您将所有的时间都花在等待文件系统上。除非您有多个仅在用户级别绑定在一起的独立驱动器(也就是说,不是LVM或其下的某些东西,如RAID),或者根本没有(例如,一个驱动器只是安装在另一个文件系统下),否则并行发出多个请求可能不会加快速度 不过,这很容易测试;为什么不试试看呢
还有一个想法:您可能会花费大量时间来生成
文件
进程并与之通信。有多个Python库使用与之相同的代码。我不想特别推荐其中一种,所以这里有一些建议
正如monkut所建议的,确保您正在进行批量提交,而不是使用sqlite自动提交每个插入。同样,sqlite每秒可以进行50000次插入,但每秒只有几十次事务 当我们进行此操作时,如果您可以将sqlite文件放在与正在扫描的文件系统不同的文件系统上(或者将其保存在内存中,直到完成,然后一次性将其写入磁盘),那么可能值得一试
最后,但最重要的是:
- 分析代码以查看热点在哪里,而不是猜测
- 创建小型数据集,并对不同的备选方案进行基准测试,以了解您能获得多少好处
os.walk
是您的瓶颈,即将发布的Python 3.5基本上是一个优化的os.walk
。我怀疑线程在这里会有多大帮助,因为这听起来像是您的代码主要是I/O绑定的。如果您真的想确定,然后,您应该对其进行基准测试,并找出时间的去向。如果我只是简单地推测一下,我想产生新的进程是不小的开销,看看吧。而且,我非常确定有一些库在PyPI上包装了fts
(我几年前自己写了一个,直到我发现一个已经完成了…),这将大大快于大多数文件系统上的scandir
(这已经比行走
)快了。或者,如果找不到,您可能需要执行子进程以查找
(是的,与我在文件中给出的正好相反)