我正在使用reportlab将一些大型库(俄语的纯文本)转换为pdf格式。
当原始文件足够小(比如,大约10-50kb)时,它可以正常工作。但如果我试图转换大文本(500kB以上),reportlab需要花费大量时间才能继续。
有人知道会有什么问题吗?

BYTES_TO_READ = 10000

def go(text):
    doc = SimpleDocTemplate("output.pdf")
    Story = [Spacer(1, 2*inch)]
    style = styles["Normal"]
    p = Paragraph(text, style)
    Story.append(p)
    doc.build(Story)

def get_text_from_file():
    source_file = open("book.txt", "r")
    text = source_file.read(BYTES_TO_READ)
    source_file.close()
    return text

go(get_text_from_file())

因此,当我试图将BYTES_TO_READ变量设置为超过200-30万时(即,只是为了看看发生了什么,而不是阅读整本书,只是其中的一部分),这需要大量的时间

最佳答案

首先让我说,我对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

关于python - reportlab性能低下,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12290583/

10-12 18:46