【问题标题】:Why are textwrap.wrap() and textwrap.fill() so slow?为什么 textwrap.wrap() 和 textwrap.fill() 这么慢?
【发布时间】:2012-08-02 15:51:49
【问题描述】:

为什么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

【问题讨论】:

  • TextWrap 包装单词,可能有很多非拉丁脚本支持,而您的简单代码会盲目地将字符串分解为 70 长度的数组。

标签: python


【解决方案1】:

分析代码显示,时间被正则表达式占用,该正则表达式旨在将输入拆分为单词。显示相同问题的精简版是:

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)

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

【讨论】:

    【解决方案2】:

    textwrap 比您的简单、流线型示例程序所做的更多很多。它构造了一个新类,编译了一些正则表达式来处理各种空格和其他可换行的字符组合等。

    这并不是一个公平的比较,尤其是因为(如 hamstergene 所述)您引用的程序 实际上并没有换行。

    【讨论】:

      【解决方案3】:

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

      ~: 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 个单词,每个单词 9 个字符,用空格分隔,运行速度快 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-09-16
        • 2012-08-10
        • 1970-01-01
        • 1970-01-01
        • 2021-09-03
        • 2011-12-08
        • 1970-01-01
        • 2016-09-28
        相关资源
        最近更新 更多