はじめに、reportlabの経験はあまりありません。これは単なる一般的な提案です。また、読んでいるテキストを適切な構造に解析およびフォーマットする方法についても正確に扱っていません。私はParagraph
テキストを書くためにクラスを使い続けています。
パフォーマンスの観点から、あなたの問題は、巨大な文字列を1回読み取ろうとし、その巨大な文字列を1つの段落として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
が、1つの大きな段落と大差ありません。最終的には、読み取っているテキストを解析してバッファーに入れ、独自の段落を決定するか、元のソースの形式である場合は行を分割することをお勧めします。
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