3

なぜ、textwrap.wrap()そしてtextwrap.fill()とても遅いのですか?たとえば、ラップトップで10000文字の文字列を折り返すには、約2秒半かかります。

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

これを、関連するStackOverflowの質問への回答から適合させたこのコードと比較してください

#!/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
4

3 に答える 3

8

コードをプロファイリングすると、入力を単語に分割することを目的とした正規表現に時間がかかることがわかります。同じ問題を示すその簡略版は次のとおりです。

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)

あなたが見つけるものは本当に速いです。ハイフンを照合するための正規表現には、テキストにスペースが含まれていない場合に病理学的なケースがあります。

于 2012-08-02T16:29:05.170 に答える
6

textwrapシンプルで合理化されたサンプルプログラムよりもはるかに多くのことを実行します。新しいクラスを構築し、いくつかの正規表現をコンパイルして、あらゆる種類の空白やその他の折り返し可能な文字の組み合わせなどを処理します。

特に(hamstergeneが指摘したように)引用されたプログラムは実際にはテキストをラップしないため、これは実際には公正な比較ではありません。

于 2012-08-02T16:02:00.630 に答える
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

ただし、スペースで区切られた9文字の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
于 2012-08-02T17:22:49.907 に答える