2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Python速度比較 regex vs startswith vs str[:word_length]

Last updated at Posted at 2020-05-24

Python速度比較 regex vs startswith vs str[:num]

はじめに

Ptyhonである文字列の前方一致を判定する方法はいくつかある。
その中で代表的な以下の3つの速度比較を行う。

  • 正規表現
  • startswith
  • str[:word_length] == word

測定方法

環境

以下の実行環境で実施する

項目
Python Version 3.8.2
OS Ubuntu 20.04

プログラム

以下のプログラムを基準にして動作を確認する。なお各変数と各関数の役割は以下の通りである。
計測したい特性に応じて変数を変化させる。

変数/関数 説明
time_logging 時間を計測するためのデコレータ
compare_regex 引数の文字列のリストのそれぞれを正規表現で比較する
compare_startswith 引数の文字列のリストのそれぞれをstartswithメソッドで比較する
compare_str 引数の文字列のリストのそれぞれの最初の文字列がtarget_wordと等しいかを比較する
target_word 比較対象となる文字列
match_word target_wordとマッチする文字列のプレフィックス
not_match_word target_wordとマッチしない文字列のプレフィックス
compare_word_num 比較する文字列を総数
compare_func 測定する関数
main 呼び出される関数
import re
import time


def time_logging(func):
    def deco(*args, **kwargs):
        stime = time.time()
        res = func(*args, **kwargs)
        etime = time.time()
        print(f'Finish {func.__name__}. Takes {round(etime - stime, 3)}s.', flush=True)
        return res

    return deco


@time_logging
def compare_regex(compare_words):
    pattern = re.compile(f'^{target_word}')
    for word in compare_words:
        if pattern.match(word):
            pass


@time_logging
def compare_startswith(compare_words):
    for word in compare_words:
        if word.startswith(target_word):
            pass


@time_logging
def compare_str(compare_words):
    length = len(target_word)
    for word in compare_words:
        if word[:length] == target_word:
            pass


target_word = f'foo'
match_word = f'{target_word}'
not_match_word = f'bar'
compare_word_num = 100_000_000
match_rate = 50
compare_func = compare_regex


def main():
    compare_words = []
    for index in range(compare_word_num):
        if index % 100 <= match_rate:
            compare_words.append(f'{match_word}_{index}')
        else:
            compare_words.append(f'{not_match_word}_{index}')

    compare_func(compare_words)


if __name__ == '__main__':
    main()

パラメータ

比較対象の文字列の長さで実行速度の傾向が変わる可能性があるため、
target_wordを5文字, 10文字, 50文字, 100文字, 500文字と変化させたときのcompare_regex, compare_startswith, compare_strの実行速度をそれぞれ計測する。

測定

単位(秒)

関数\文字数 5 10 50 100 500
compare_regex 11.617 12.044 16.126 18.837 66.463
compare_startswith 6.647 6.401 6.241 6.297 6.931
compare_str 5.941 5.993 4.87 5.449 8.875

chart.png

考察

速度的には、あらゆる文字数でstartswithまたは、str[:word_length]で実装すべきである。比較対象の文字列の影響をもっとも受けないstartswithがもっともおすすめ。
また可読性という観点でも一番好き。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?