« Fontconfigを使ってフォントの横幅を変える方法 | トップページ

2017年7月20日 (木)

Python3のenumは遅い?

Python3.4からenumがサポートされたというので使ってみたところ、どうも遅いらしいです。

以前自分で作ったテキスト処理スクリプトの字句解析部にステートマシンを使っていたので、そのステートを示す定数をenumに変えたところ、もとの整数の変数で代用したものでは2.1秒くらいの処理だったのが、4.2秒くらいに増加しました。

整数の変数を使ったものはこんなコードです。ちなみにこの関数は1行ごとに呼び出していますが、range(4)を外に追い出してもほとんど速度は変わりませんでした。

def _split_words(line):
    ...
    ( ST_INDENT, ST_FIRST_CHAR, ST_SEARCH_TOKEN, ST_TOKEN ) = range(4)
    ( QT_SINGLE, QT_DOUBLE, QT_BACK, QT_NOTHING ) = range(4)
    st = ST_INDENT
    ...
    for idx in range(len(line)):
        ...
        if st==ST_INDENT:
            ...
            st = ST_FIRST_CHAR
        elif st==ST_FIRST_CHAR:
            ....

enumを使ったものは次のコードになります。forループは1文字ずつ全部まわる動作回数の多いコードになりますが、ステート定数は比較と代入しかしていません。

_split_words_st = enum.Enum('_split_words_st', 'INDENT FIRST_CHAR SEARCH_TOKEN TOKEN')
_split_words_qt = enum.Enum('_split_words_qt', 'SINGLE DOUBLE BACK NOTHING')

def _split_words(line):
    ...
    ST = _split_words_st
    QT = _split_words_qt
    st = ST.INDENT
    ...
    for idx in range(len(line)):
        ...
        if st==ST.INDENT:
            ...
            st = ST.FIRST_CHAR
        elif st==ST.FIRST_CHAR:
            ....

OSはLinuxで、Pythonは3.5.3と3.6.2で確認しました。実行時間は_split_words()関数の呼び出し前後をtime.perf_counter()で囲って測っていますが、8万回くらいある呼び出しそれぞれの実行時間を合計しています。

« Fontconfigを使ってフォントの横幅を変える方法 | トップページ

パソコン・インターネット」カテゴリの記事

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/2064309/71194410

この記事へのトラックバック一覧です: Python3のenumは遅い?:

« Fontconfigを使ってフォントの横幅を変える方法 | トップページ