share facebook facebook twitter menu hatena pocket slack

2017.01.12 THU

ショロカレ 16 日目 | 初老と Python (3) 〜 俺の雑な Python スクリプトがどれだけ遅いのかを関数毎に計測する 〜

川原 洋平

WRITTEN BY 川原 洋平

これは

初老丸アドベントカレンダー 16 日目の記事です。

初老丸 Advent Calendar 2016 - Qiita
集え、初老丸達よ。初老丸達による世界に向けた技術的(又はそれに関連する)な物語を綴るカレンダーです。我こそ初老丸という方、初老丸予備軍の方も奮ってご参加下さい。

qiita.com

ということで、小ネタ大ネタを交えて 12/25 まで張り切っていきましょう。

初老と Python (3) 〜 俺の雑なスクリプトがどれだけ遅いのかを関数毎に計測する 〜

脱・なんとなく遅い

「このスクリプトを作ったのはだれだー。なんとなく遅いぞ」って言われてもアレなので、どこの関数が遅いのかとか簡単に計測できたらなあと思っていたら以下の記事を読んで目からウロコだったので試してみた。

Pythonスクリプトのパフォーマンス計測ガイド | Yakst
Pythonスクリプトの速度を計測し、そのボトルネックを探る。さらに、メモリ使用量、メモリリークの原因特定までの調査方法を解説する。

yakst.com

Timer クラス

withステートメントを使って関数の前後で時間を測って計測するので、以下のような Timer クラスを追加するところから始めるようです。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time

class Timer(object):
    def __init__(self, verbose=False):
        self.verbose = verbose

    def __enter__(self):
        self.start = time.time()
        return self

    def __exit__(self, *args):
        self.end = time.time()
        self.secs = self.end - self.start
        self.msecs = self.secs * 1000  # millisecs
        if self.verbose:
            print 'elapsed time: %f ms' % self.msecs

雑なスクリプト

ここのスクリプトを少し修正。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import time
import itertools
from operator import itemgetter
from timer import Timer

def takaraduka():
    top_stars = [
     {'名前': '明日海 りお', 'クラス': '花組'},
     {'名前': '花乃 まりあ', 'クラス': '花組'},
     {'名前': '珠城 りょう', 'クラス': '月組'},
     {'名前': '愛希 れいか', 'クラス': '月組'},
     {'名前': '早霧 せいな', 'クラス': '雪組'},
     {'名前': '咲妃 みゆ', 'クラス': '雪組'},
     {'名前': '紅 ゆずる', 'クラス': '星組'},
     {'名前': '綺咲 愛里', 'クラス': '星組'},
     {'名前': '朝夏 まなと', 'クラス': '宙組'},
     {'名前': '実咲 凜音', 'クラス': '宙組'},
    ]

    top_stars = sorted(top_stars, key=itemgetter('クラス'))
    for key, value in itertools.groupby(top_stars, key=itemgetter('クラス')):
        print '■ ' + key
        for i in value:
            print i.get('名前')

    time.sleep(0.1)

if __name__ == '__main__':
    with Timer() as t:
        takaraduka()
    print "= > elasped time : %s s" % t.secs

実行する関数(takaraduka())の前後にwith ステートメントを利用してタイマーを仕込む。
ちょっとsleep 入れたりして時間稼ぎ。

実行

以下のように関数(takaraduka())の処理時間が出力される。

bash-3.2$ python test.py
■ 宙組
朝夏 まなと
実咲 凜音
■ 星組
紅 ゆずる
綺咲 愛里
■ 月組
珠城 りょう
愛希 れいか
■ 花組
明日海 りお
花乃 まりあ
■ 雪組
早霧 せいな
咲妃 みゆ
=> elasped time : 0.105126142502 s

elasped time : 0.105126142502 s ということで、処理時間は 0.1 秒程。単体のスクリプトだとなんてことないけど、大きなスクリプトになると 0.1 秒が命取りになるので注意しましょう。適宜、タイマーを仕込んで処理時間には目を光らせましょう。自戒を込めて。

以上

メモでした。

元記事はこちら

ショロカレ 16 日目 | 初老と Python (3) 〜 俺の雑な Python スクリプトがどれだけ遅いのかを関数毎に計測する 〜