使用Python

时间:2015-05-07 05:59:33

标签: python linux file sqlite subprocess

任务:

我正在处理存储在外部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可能是个问题。

问题:

  1. 是否有更快的替代os.walk?
  2. 线程是否会紧固?

1 个答案:

答案 0 :(得分:6)

  

是否有更快的替代os.walk

是。事实上,多重。

  • scandir(将在3.5中的stdlib中)明显快于walk
  • C函数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文件放在与您正在扫描的文件系统不同的文件系统上(或将其保留在内存中,直到您完成,请将其写入这可能是值得一试的。

最后,但最重要的是:

  • 描述您的代码以查看热点的位置,而不是猜测。
  • 创建小型数据集并对不同的替代方案进行基准测试,以了解您获得的收益。