Pythonで他にはない特殊な書き方といえば、内包表記ですかね。Haskellでもかけるみたいな話聞いたことあるけど。実際内包表記は読みやすく、たいてい高速に動くので推奨される書き方と思います。ベンチマークを測ってみたので参考になればと。
今回のコード
今回速さを測るための指標となるコードは以下になります。
至ってシンプルなforループが以下です。
symbols = '$¢£¥€¤'
def non_ascii(c):
return c > 127
codes = []
for s in symbols:
if ord(s) > 127:
codes.append(ord(s))
これを下に複数の書き方に対して処理速度を測ります。
いざ実験
今回試すものが以下になります。
- ただのforループ
- 内包表記
- 内包表記 + 自作関数(non_adcii)
- filter + lambda
- filter + 自作関数(non_ascii)
これらに関して測ってみます。 コードが以下になります。
import timeit
TIMES = 10000
SETUP = """
symbols = '$¢£¥€¤'
def non_ascii(c):
return c > 127
"""
def clock(label, cmd):
res = timeit.repeat(cmd, setup=SETUP, number=TIMES)
print(label, *('{:.3f}'.format(x) for x in res))
if __name__ == "__main__":
clock('for-loop :', 'codes = []\nfor s in symbols:\n\tif ord(s) > 127: codes.append(ord(s))\ncodes')
clock('listcomp :', '[ord(s) for s in symbols if ord(s) > 127]')
clock('listcomp + func :', '[ord(s) for s in symbols if non_ascii(ord(s))]')
clock('filter + lambda :', 'list(filter(lambda c: c > 127, map(ord, symbols)))')
clock('filter + func :', 'list(filter(non_ascii, map(ord, symbols)))')
これらから得られる結果がこんな感じです。(人による)
for-loop : 0.009 0.009 0.009 0.009 0.009
listcomp : 0.008 0.008 0.008 0.008 0.008
listcomp + func : 0.012 0.013 0.013 0.012 0.012
filter + lambda : 0.011 0.013 0.012 0.011 0.013
filter + func : 0.014 0.014 0.014 0.014 0.013
これはまだループも小さいので差はありませんが、安定して早く動いているのは内包表記ですね。
読みやすく、高速に動くことが多い内包表記でした。実際に導入してみてはいかがでしょか。
今回は実験だけ示して終わります〜〜.