Doge log

Abby CTO 雑賀 力王のオフィシャルサイトです

スケジューリング

何秒後に実行する、キューにためこむイメージで後々、まとめて実行するなど
スケジューリングして実行するサンプル。

方法は2つあってbisectかheapq。
どちらもソート済みにするって点は同じかな。

bisect
import bisect
import time

timers = []

def add_timer(second, cb, *args, **kwargs):
    scheduled_time =  time.time() + second
    insert = bisect.insort_right
    insert(timers, (scheduled_time, (cb, args, kwargs)))

def fire_timer():
    now = time.time()
    last = bisect.bisect_right(timers, (now, ()))
    for i in xrange(last):
        cb, args, kwargs = timers[i][1]
        cb(*args, **kwargs)
    del timers[:last]

def test(text):
    print(text)

add_timer(5, test, "5-1")
add_timer(5, test, "5-2")
add_timer(2, test, "2")
add_timer(0, test, "0")
add_timer(1, test, "1")

while len(timers):
    fire_timer()
    time.sleep(0.5)

bisectで対象になる境界線を引きにいってから取り出して実行。
heapqに比べ現在時刻との比較の回数が少ない。

heapq
from heapq import *
import time

timers = []

def add_timer(second, cb, *args, **kwargs):
    scheduled_time =  time.time() + second
    heappush(timers, (scheduled_time, (cb,args, kwargs)))

def fire_timer():
    now = time.time()
    while timers and timers[0][0] <= now:
        t = heappop(timers)
        cb, args, kwargs = t[1]
        cb(*args, **kwargs)

def test(text):
    print(text)

add_timer(5, test, "5-1")
add_timer(5, test, "5-2")
add_timer(2, test, "2")
add_timer(0, test, "0")
add_timer(1, test, "1")

while len(timers):
    fire_timer()
    time.sleep(0.5)

heapなので先頭が最小となる。
先頭をひたすら比較していく。

実際に使われてる方式

  1. eventlet bisect方式
  2. twisted heapq方式

さてどっちを使おうかな。。。