为什么textwrap.wrap()和textwrap.fill()这么慢?

时间:2012-08-02 15:51:50

标签: python

为什么textwrap.wrap()textwrap.fill()这么慢?例如,要在我的笔记本电脑上包装10000个字符的字符串需要将近两秒半。

$ python -m timeit -n 10 -s 's = "A" * 10000; import textwrap' 'textwrap.fill(s)'
10 loops, best of 3: 2.41 sec per loop

将此代码与此an answer to a related Stack Overflow question

改编的代码进行比较
#!/usr/bin/env python
# simplewrap.py
def fill(text, width=70):
    return '\n'.join(text[i:i+width] for i in
                     range(0, len(text), width))

包装文本的数量级比textwrap

$ python -m timeit -n 10 -s 's = "A" * 10000; import simplewrap' 'simplewrap.fill(s)'
10 loops, best of 3: 37.2 usec per loop

3 个答案:

答案 0 :(得分:7)

对代码进行概要分析表明,时间由用于将输入拆分为单词的正则表达式占用。展示相同问题的精简版本是:

import re
s = "A" * 10000
wordsep_re = re.compile(
    r'\w+[^\W]-'
    )
wordsep_re.split(s)

我相信Python使用递归回溯来匹配正则表达式。我认为最新的事情是python一直试图匹配 - 并且失败,因此不得不备份。

您可以使用:

textwrap.fill(s, break_on_hyphens = False)

你会发现它真的很快。当文本中没有任何空格时,匹配连字符的正则表达式具有病态情况。

答案 1 :(得分:6)

textwrap比简单,简化的示例程序做的更多很多。它构造一个新类,编译一些正则表达式来处理各种空格和其他可包装的字符组合等。

这不是一个公平的比较,特别是因为(正如hamstergene所说)你引用的程序 实际上并没有包装文本。

答案 2 :(得分:2)

您正在测试一个特定的病理案例。一个不可破坏的字符串表现非常糟糕:

~: python -m timeit -n 10 -s 's = "A"*10000; import textwrap' 'textwrap.fill(s)'
10 loops, best of 3: 1.62 sec per loop

但1000个单词,每个九个字符,以空格分隔,运行速度快300倍:

~: python -m timeit -n 10 -s 's = "AAAAAAAAA " * 1000; import textwrap' 'textwrap.fill(s)'
10 loops, best of 3: 5.46 msec per loop