- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前成功地使用了一个 python 2.7 脚本,它在一个巨大的目录/文件路径上递归循环,收集所有文件的路径,获取这些文件的 mtime 以及具有相同路径和名称的各个文件的 mtime,但作为比较的pdf文件。我在 python 2.7 脚本中使用 scandir.walk() ,在 python 3.7 中使用 os.walk() ,最近更新为也使用 scandir 算法(没有额外的 stat() 调用)。
但是,脚本的 python 3 版本仍然明显较慢!这不是由于算法的 scandir/walk 部分,但显然是由于 getmtime 算法(然而,它在 python2 和 3 中是相同的调用)或巨大列表的处理(我们正在谈论 ~此列表中有 500.000 个条目)。
知道可能导致此问题的原因以及如何解决此问题吗?
#!/usr/bin/env python3
#
# Imports
#
import sys
import time
from datetime import datetime
import os
import re
#
# MAIN THREAD
#
if __name__ == '__main__':
source_dir = '/path_to_data/'
# Get file list
files_list = []
for root, directories, filenames in os.walk(source_dir):
# Filter for extension
for filename in filenames:
if (filename.lower().endswith(('.msg', '.doc', '.docx', '.xls', '.xlsx'))) and (not filename.lower().startswith('~')):
files_list.append(os.path.join(root, filename))
# Sort list
files_list.sort(reverse=True)
# For each file, the printing routine is performed (including necessity check)
all_documents_counter = len(files_list)
for docfile_abs in files_list:
print('\n' + docfile_abs)
# Define files
filepathname_abs, file_extension = os.path.splitext(docfile_abs)
filepath_abs, filename = os.path.split(filepathname_abs)
# If the filename does not have the format # # # # # # # *.xxx (e.g. seven numbers), then it is checked whether it is referenced in the databse. If not, it is moved to a certain directory
if (re.match(r'[0-9][0-9][0-9][0-9][0-9][0-9][0-9](([Aa][0-9][0-9]?)?|(_[0-9][0-9]?)?|([Aa][0-9][0-9]?_[0-9][0-9]?)?)\...?.?', filename + file_extension) is None):
if any(expression in docfile_abs for expression in ignore_subdirs):
pass
else:
print('Not in database')
# DOC
docfile_rel = docfile_abs.replace(source_dir, '')
# Check pdf
try:
pdf_file_abs = filepathname_abs + '.pdf'
pdf_file_timestamp = os.path.getmtime(pdf_file_abs)
check_pdf = True
except(FileNotFoundError):
check_pdf = False
# Check PDF
try:
PDF_file_abs = filepathname_abs + '.PDF'
PDF_file_timestamp = os.path.getmtime(PDF_file_abs)
check_PDF = True
except(FileNotFoundError):
check_PDF = False
# Check whether ther are lowercase or uppercase extension and decide what to do if there are none, just one or both present
if (check_pdf is True) and (check_PDF is False):
# Lower case case
pdf_extension = '.pdf'
pdffile_timestamp = pdf_file_timestamp
elif (check_pdf is False) and (check_PDF is True):
# Upper case case
pdf_extension = '.PDF'
pdffile_timestamp = PDF_file_timestamp
elif (check_pdf is False) and (check_PDF is False):
# None -> set timestampt to zero
pdf_extension = '.pdf'
pdffile_timestamp = 0
elif (check_pdf is True) and (check_PDF is True):
# Both are present, decide for the newest and move the other to a directory
if (pdf_file_timestamp < PDF_file_timestamp):
pdf_extension = '.PDF'
pdf_file_rel = pdf_file_abs.replace(source_dir, '')
pdffile_timestamp = PDF_file_timestamp
elif (PDF_file_timestamp < pdf_file_timestamp):
pdf_extension = '.pdf'
PDF_file_rel = PDF_file_abs.replace(source_dir, '')
pdffile_timestamp = pdf_file_timestamp
# Get timestamps of doc and pdf files
try:
docfile_timestamp = os.path.getmtime(docfile_abs)
except OSError:
docfile_timestamp = 0
# Enable this to force a certain period to be printed
DateBegin = time.mktime(time.strptime('01/02/2017', "%d/%m/%Y"))
DateEnd = time.mktime(time.strptime('01/03/2017', "%d/%m/%Y"))
# Compare stimestamps and print or not
if (pdffile_timestamp < docfile_timestamp) or (pdffile_timestamp == 0):
# Inform that there should be printed
print('\tPDF should be printe.')
else:
# Inform that there was no need to print
print('\tPDF is up to date.')
# Exit
sys.exit(0)
最佳答案
不确定是什么解释了差异,但即使 os.walk
已增强为使用 scandir
,它也不会进一步扩展到 getmtime
调用,它再次访问文件属性。
最终目标是不调用os.path.getmtime
根本。
os.walk
中的加速是关于不执行两次 stat
以了解对象是目录还是文件。但是内部 DirEntry
对象(scandir
产生)永远不会公开,因此您不能重用它来检查文件时间。
如果不需要回避,可以用os.scandir
完成:
for dir_entry in os.scandir(r"D:\some_path"):
print(dir_entry.is_dir()) # test for directory
print(dir_entry.stat()) # returns stat object with date and all
循环内的那些调用是零成本完成的,因为 DirEntry
对象已经缓存了此信息。
因此,要保存 getmtime
调用,您必须递归地获取 DirEntry
对象。
这里没有本地方法,但是有 recipies,示例在这里:How do I use os.scandir() to return DirEntry objects recursively on a directory tree?
通过这样做,您的代码在 python 2 和 python 3 中会更快,因为每个对象只有 1 次 stat
调用,而不是 2 次。
编辑:在您编辑显示代码后,您似乎正在从其他条目构建 pdf 名称,因此您不能依赖 DirEntry
结构来获取时间,甚至不确定该文件存在(如果您使用的是 Windows,则无需测试 pdf 和 PDF,因为文件名不区分大小写)。
最好的策略是建立一个包含相关时间和所有文件的大数据库(使用字典)然后扫描它。我已经成功地使用这种方法在一个包含 3500 万个文件的慢速网络驱动器上找到旧/大文件。在我个人的例子中,扫描文件一次,并将结果转储到一个大的 csv 文件中(需要几个小时,对于 6Gb 的 csv 数据),然后进一步的后处理加载数据库并执行各种任务(更快,因为没有磁盘访问参与)
关于Python 2 vs. 3 慢 os.path.getmtime() 与巨大的文件列表 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54829029/
如标题所示,ans_list是一个答案列表,ans_index是一个数字(答案在词汇表中的索引,但与atm无关) 这里生成的 tree.anslist 是什么? (例如,仅针对第一个),忽略迭代。 f
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将具有一个元素的东西拿走。 这与 How do I “flatte
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将带有一个元素的东西拿走。 这与 How do I “flatte
这个问题已经有答案了: Convert nested list to 2d array (3 个回答) 已关闭 7 年前。 java中有没有快捷方式可以转换 List> 到 String[][] ?
我在排序时遇到问题 List> 。我创建了一个自定义比较器,在其中编写了对数据进行排序的代码。 public class CustomComparator implements Comparator
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Java Generics: Cannot cast List to List? 我只是想知道为什么下面的java代
试图想出一个 LINQy 方法来做到这一点,但我什么也没想到。 我有一个对象列表<>,其中包含一个属性,该属性是逗号分隔的字母代码列表: lst[0].codes = "AA,BB,DD" lst[1
假设我有这些任务: points = [] point = (1, 2) 我怎么会这样做: points += point 它工作得很好,并且给了我点 = [1, 2]。但是,如果我这样做: poin
如何在 scala 中将 List[Task[List[Header]]] 类型转换为 Task[List[Header]]。 我有一个方法返回 Task[List[Header]] 并多次调用 do
如何在 Java 中查找二维列表的元素? 我有一个参数为 List> 的函数我想知道如何找到这个列表的行和列。 最佳答案 如果你喜欢 List> obj 然后你就可以像这样访问 obj.get(cur
分配 List到 List工作正常。 分配 List>到 List>不编译。 代码 public class Main { public static void main(String[] a
我正在用 Java 编写一个方法,该方法必须接收并迭代 Serializable 的 List。 有什么区别: public void myMethod(List list) { } 和 public
我看到很多人想用 mvvm 更新网格/列表/树的一部分,但他们不想刷新整个列表。 对于所有遇到此问题的人,我做了以下示例。 希望这对你有用。 最佳答案 这是一个简单的例子。整个代码中最重要的是: Bi
我正在为现有的 C++ 库编写包装器,该库使用列表,其中 T 是自定义结构。我被建议使用 vector 而不是列表,但我试图避免修改库。 为了更好地理解这个场景,我做了一个简单的应用程序,使用一个列表
List list List list 这两种声明有什么区别吗? 谢谢, 最佳答案 是的。 List可以包含所有派生自 Base 的不同事物的混合物. List包含同质项(从某种意义上说,它们必须全部
有人可以尽可能详细地解释以下类型之间的区别吗? List List List 让我更具体一点。我什么时候想使用 // 1 public void CanYouGiveMeAnAnswer(List l
我有一个元组列表,每个元组都是一对列表。所以我的数据看起来像: mylist = [(['foo', 'bar'], ['bar', 'bar']),(['bar', 'bar'],['bar', '
也许是一个时髦的标题,但我遇到了以下问题: 给定一个类型为 (a * b) list 的列表,我想创建一个类型为 (a * b list) list 的新列表。一个例子: 给定列表 let testL
我是一名优秀的程序员,十分优秀!