任务:
我正在处理存储在外部USB磁盘上的4 TB数据/文件:图像,HTML,视频,可执行文件等。
我想使用以下架构索引sqlite3数据库中的所有文件:
path TEXT, mimetype TEXT, filetype TEXT, size INT
到目前为止:
我以递归方式通过挂载目录运行os.walk,使用python的子进程执行linux file
命令,并使用os.path.getsize()获取大小。最后将结果写入数据库,存储在我的计算机上 - 当然,usb安装了-o ro。顺便说一下,没有线程
您可以在此处查看完整代码http://hub.darcs.net/ampoffcom/smtid/browse/smtid.py
问题:
代码非常慢。我意识到,直接结构越深,代码就越慢。我想,os.walk可能是个问题。
问题:
答案 0 :(得分:6)
是否有更快的替代
os.walk
?
是。事实上,多重。
scandir
(将在3.5中的stdlib中)明显快于walk
。fts
明显快于scandir
。我非常确定PyPI上有包装器,虽然我不知道一个副手推荐,并且通过ctypes
或{{1}并不难以使用如果你知道任何C。find
工具使用cffi
,如果您无法直接使用fts
,则可以始终subprocess
。线程是否可以解决问题?
这取决于我们没有的系统详细信息,但是......您将花费所有时间等待文件系统。除非你有多个独立的驱动器只在用户级绑定在一起(也就是说,不是LVM或RAID之下的某些东西),或者根本没有(例如,一个只是安装在另一个文件系统下),并行的多个请求可能不会加快速度。
不过,这很容易测试;为什么不尝试一下呢?
还有一个想法:您可能会花费大量时间来产生并与那些fts
进程进行通信。有多个Python库使用与它相同的libmagic
。我不想特别推荐其中一个,所以这里search results。
正如monkut建议的那样,请确保您正在进行批量提交,而不是使用sqlite自动提交每个插件。作为the FAQ explains,sqlite每秒可以执行~50000次插入,但每秒只能处理几十次。
虽然我们正在使用它,但如果您可以将sqlite文件放在与您正在扫描的文件系统不同的文件系统上(或将其保留在内存中,直到您完成,请将其写入这可能是值得一试的。
最后,但最重要的是: