让我先说我在reportlab方面没有太多经验。这只是一个一般性建议。它也没有确切地处理你应该如何解析和格式化你正在阅读的文本到适当的结构。我只是继续使用Paragraph
该类来编写文本。
在性能方面,我认为您的问题与尝试读取一个巨大的字符串并将该巨大的字符串作为单个段落传递给reportlab 有关。如果你想一想,什么段落是真正的 500k 字节?
您可能想要做的是以较小的块读取,并构建您的文档:
def go_chunked(limit=500000, chunk=4096):
BYTES_TO_READ = chunk
doc = SimpleDocTemplate("output.pdf")
Story = [Spacer(1, 2*inch)]
style = styles["Normal"]
written = 0
with open("book.txt", "r") as source_file:
while written < limit:
text = source_file.read(BYTES_TO_READ)
if not text:
break
p = Paragraph(text, style)
Story.append(p)
written += BYTES_TO_READ
doc.build(Story)
处理总共 500k 字节时:
%timeit go_chunked(limit=500000, chunk=4096)
1 loops, best of 3: 1.88 s per loop
%timeit go(get_text_from_file())
1 loops, best of 3: 64.1 s per loop
同样,显然这只是将您的文本分成任意段落,即 BYTES_TO_READ
值的大小,但它与一个巨大的段落没有太大区别。最终,您可能希望将正在阅读的文本解析到缓冲区中,并确定您自己的段落,或者如果这是您原始源的格式,则只需按行拆分:
def go_lines(limit=500000):
doc = SimpleDocTemplate("output.pdf")
Story = [Spacer(1, 2*inch)]
style = styles["Normal"]
written = 0
with open("book.txt", "r") as source_file:
while written < limit:
text = source_file.readline()
if not text:
break
text = text.strip()
p = Paragraph(text, style)
Story.append(p)
written += len(text)
doc.build(Story)
表现:
%timeit go_lines()
1 loops, best of 3: 1.46 s per loop