Python: 为什么打开 XFA pdf 文件比打开相同大小的 txt 文件需要更长的时间?
Python: Why opening an XFA pdf file takes longer than a txt file of same size?
我目前正在开发一些 python 代码来从 14000 个 pdf 中提取数据(每个 pdf 7 Mb)。它们是由 Adobe LiveCycle Designer 11.0 制作的动态 XFA,因此它们包含需要稍后解码的流(因此如果有任何区别,则有一些非 ascii 字符)。
我的问题是,在这些文件上调用 open() 每次大约需要 1 秒,甚至更多。
我对通过复制粘贴字符创建的 13Mb 文本文件尝试了相同的操作,打开它们所需的时间不到 0.01 秒。 当我用 open() 打开动态 pdf 时,这个时间增加来自哪里?我可以避免这个瓶颈吗?
我像这样使用 cProfile 获得了这些时间:
from cProfile import Profile
profiler = Profile()
profiler.enable()
f = open('test.pdf', 'rb')
f.close()
profiler.disable()
profiler.print_stats('tottime')
对于给定的 xfa pdf,print_stats 的结果如下:
io.open() takes around 1 second to execute once
补充信息:
我注意到,在过去 15 或 30 分钟内打开同一个 pdf 文件时,打开时间快了大约 10 倍,即使我删除了项目中的 __pycache__
目录也是如此。尽管我的电脑上只剩下 50 Gb,但无论经过多少时间都可以应用这种速度提升的解决方案可能是值得的。
此外,pdf 的并行处理不是一种选择,因为我只有 1 个空闲核心来 运行 我的实现...
要解决此问题,您可以执行以下操作之一:
- 指定 files/directories/extensions 从 Windows Defender 设置中排除(无实时扫描)
- 暂时关闭 Windows Defender 的
real time protection
。
- 以编码格式保存文件,其中 Windows Defender 无法检测到其他 files/websites 的链接并在读取时对其进行解码。 (我没试过)
正如“user2357112 支持 monica”在评论中所说,罪魁祸首是防病毒软件在将文件提供给 python 之前扫描文件。
我可以通过在打开任务管理器的同时调用文件列表 open()
来验证这一点。 Python 使用了几乎 0% 的 CPU 而 Service antivirus Microsoft Defender
已经用完了我的一个核心。
我将结果与我的脚本的另一个 运行 进行了比较,在该脚本中我多次打开了同一个文件并且 python 核心已达到最大值,而防病毒软件保持在 0%。
我尝试使用 Windows Defender 运行 快速扫描单个 pdf 文件 2 次。第一次执行导致在 1 秒内扫描了 800 个文件(因此 open()
执行延迟了 1 秒),第二次扫描导致立即扫描了一个文件。
解释:
Windows Defender 扫描文件夹中写入的所有 file/internet 链接,这就是扫描它们需要这么长时间的原因,也是第一份报告中扫描了大约 800 个文件的原因。 Windows defender 保留自打开电脑后扫描的文件缓存。 Windows Defender 不需要重新扫描未链接到互联网的文件。但是 XFA 包含指向网站的链接。由于无法判断网站是否被恶意修改,因此需要定期重新扫描包含它们的文件以确保它们仍然安全。
我目前正在开发一些 python 代码来从 14000 个 pdf 中提取数据(每个 pdf 7 Mb)。它们是由 Adobe LiveCycle Designer 11.0 制作的动态 XFA,因此它们包含需要稍后解码的流(因此如果有任何区别,则有一些非 ascii 字符)。
我的问题是,在这些文件上调用 open() 每次大约需要 1 秒,甚至更多。
我对通过复制粘贴字符创建的 13Mb 文本文件尝试了相同的操作,打开它们所需的时间不到 0.01 秒。 当我用 open() 打开动态 pdf 时,这个时间增加来自哪里?我可以避免这个瓶颈吗?
我像这样使用 cProfile 获得了这些时间:
from cProfile import Profile
profiler = Profile()
profiler.enable()
f = open('test.pdf', 'rb')
f.close()
profiler.disable()
profiler.print_stats('tottime')
对于给定的 xfa pdf,print_stats 的结果如下: io.open() takes around 1 second to execute once
补充信息:
我注意到,在过去 15 或 30 分钟内打开同一个 pdf 文件时,打开时间快了大约 10 倍,即使我删除了项目中的 __pycache__
目录也是如此。尽管我的电脑上只剩下 50 Gb,但无论经过多少时间都可以应用这种速度提升的解决方案可能是值得的。
此外,pdf 的并行处理不是一种选择,因为我只有 1 个空闲核心来 运行 我的实现...
要解决此问题,您可以执行以下操作之一:
- 指定 files/directories/extensions 从 Windows Defender 设置中排除(无实时扫描)
- 暂时关闭 Windows Defender 的
real time protection
。 - 以编码格式保存文件,其中 Windows Defender 无法检测到其他 files/websites 的链接并在读取时对其进行解码。 (我没试过)
正如“user2357112 支持 monica”在评论中所说,罪魁祸首是防病毒软件在将文件提供给 python 之前扫描文件。
我可以通过在打开任务管理器的同时调用文件列表 open()
来验证这一点。 Python 使用了几乎 0% 的 CPU 而 Service antivirus Microsoft Defender
已经用完了我的一个核心。
我将结果与我的脚本的另一个 运行 进行了比较,在该脚本中我多次打开了同一个文件并且 python 核心已达到最大值,而防病毒软件保持在 0%。
我尝试使用 Windows Defender 运行 快速扫描单个 pdf 文件 2 次。第一次执行导致在 1 秒内扫描了 800 个文件(因此 open()
执行延迟了 1 秒),第二次扫描导致立即扫描了一个文件。
解释:
Windows Defender 扫描文件夹中写入的所有 file/internet 链接,这就是扫描它们需要这么长时间的原因,也是第一份报告中扫描了大约 800 个文件的原因。 Windows defender 保留自打开电脑后扫描的文件缓存。 Windows Defender 不需要重新扫描未链接到互联网的文件。但是 XFA 包含指向网站的链接。由于无法判断网站是否被恶意修改,因此需要定期重新扫描包含它们的文件以确保它们仍然安全。