And*_*eas 6 python memory pdf pypdf2
我希望在纯python的内存中有效地串联(附加)一堆小pdf。具体来说,通常情况是将500张单页pdf合并为一个,每个pdf大小约为400 kB。假设pdf可作为内存中的可迭代对象使用,例如一个列表:
my_pdfs = [pdf1_fileobj, pdf2_fileobj, ..., pdfn_fileobj] # type is BytesIO
Run Code Online (Sandbox Code Playgroud)
其中每个pdf_fileobj均为BytesIO类型。然后,基本内存使用量约为200 MB(500 pdfs,每个400kB)。
理想情况下,我希望以下代码总共使用不超过400-500 MB的内存(包括my_pdfs
)进行连接。但是,情况似乎并非如此,最后一行的调试语句表明以前的最大内存接近700 MB。此外,使用Mac os x资源监视器,当到达最后一行时,分配的内存指示为600 MB。
运行gc.collect()
将其减少到350 MB(几乎太好了?)。在这种情况下,为什么我必须手动运行垃圾收集来摆脱合并垃圾?我已经(可能)看到了这种情况,可能会导致内存积聚,但情况略有不同,我将略过。
import PyPDF2
import io
import resources # For debugging
def merge_pdfs(iterable):
''' Merge pdfs in memory '''
merger = PyPDF2.PdfFileMerger()
for pdf_fileobj in iterable:
merger.append(pdf_fileobj)
myio = io.BytesIO()
merger.write(myio)
merger.close()
myio.seek(0)
return myio
my_concatenated_pdf = merge_pdfs(my_pdfs)
# Print the maximum memory usage
print('Memory usage: %s (kB)' % resource.getrusage(resource.RUSAGE_SELF).ru_maxrss)
Run Code Online (Sandbox Code Playgroud)
merger.write(myio)
鉴于所有情况都发生在ram中,所以它的运行速度似乎确实很慢。谢谢!
问:为什么上面的代码需要近 700 MB 的内存才能合并 200 MB 的 pdf?400 MB + 开销还不够吗?我该如何优化它?
答:因为.append
创建一个新的流对象,然后使用merger.write(myio)
,这会创建另一个流对象,并且内存中已经有 200 MB 的 pdf 文件,因此 3*200 MB。
问:当相关变量已经超出范围时,为什么我需要手动运行垃圾收集来清除 PyPDF2 合并垃圾?
答:这是 PyPDF2 中的一个已知问题。
问:这个一般方法怎么样?这种情况适合使用BytesIO吗?
答:考虑到内存问题,您可能想尝试不同的方法。也许逐一合并,暂时将文件保存到磁盘,然后从内存中清除已经合并的文件。
归档时间: |
|
查看次数: |
904 次 |
最近记录: |