[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.24 gauche.time - 時間の計測

Module: gauche.time

Schemeコードの実行時間を測る2つの単純な方法を提供します。 インタラクティブな使用に便利なtimeマクロ及び、 プログラム中に埋め込んで使える<time-counter>オブジェクトです。

Macro: time expr expr2 …

expr expr2 … を順に評価し、最後の式の結果を返します。 結果が返される前に、全ての式の評価にかかった実(経過)時間および ユーザースペース、カーネルスペースで費されたCPU時間がカレントエラーポートに 報告されます。

現在の実装は、経過時間に対してはsys-gettimeofday (時間参照)を、CPU時間に対してはsys-times (システムへの問い合わせ参照)を用いています。従って、 それぞれの数値の分解能はこれらの手続きが用いているシステムコールに依存します。 CPU時間は10ms単位で、経過時間はそれより細かいことが多いです。 但しgettimeofday(2)コールをサポートしていないOSでは経過時間が最悪の場合 秒単位になります。

 
gosh> (time (length (sort (call-with-input-file "/usr/share/dict/words" port->string-list))))
;(time (length (sort (call-with-input-file "/usr/share/dict/words" port- ...
; real   0.357
; user   0.350
; sys    0.000
45427
Class: <time-counter>

時間カウンタの抽象クラスです。時間カウンタは 時間の経過と共にその値が増加してゆく一種のタイマーです。 何度でもカウントを止めたり開始したりできます。 カウンタの値はカウントが止まっている時に読み出すことができます。 複数の時間カウンタを使えば、 例えばループ中の二つの部分について費される時間を別々に計測することもできます。

具体的なサブクラスが、どの時間をカウントするかを決定します。 時間カウンタを使うには、下に挙げるサブクラスのいずれかを インスタンシエイトしなければなりません。

Class: <real-time-counter>
Class: <user-time-counter>
Class: <system-time-counter>
Class: <process-time-counter>

それぞれ、実経過時間、ユーザースペースCPU時間、カーネルスペースCPU時間、 総CPU時間 (ユーザー+カーネル)を計測する時間カウンタのクラスです。

Method: time-counter-start! (counter <time-counter>)
Method: time-counter-stop! (counter <time-counter>)

時間カウンタcounterを開始/停止します。カウンタが走っている間の時間が、 カウンタが停止した時点でカウンタの値に加算されます。

開始/停止の対はネストすることができます。その場合は、一番外側の対のみが 有効です。 つまり、既に走っているカウンタに対しtime-counter-start!を呼んでも 何も起こりませんが、一度余分にtime-counter-stop!を呼ばないと カウンタは止まりません。 これは、内部に既に開始/停止の対を含んでいるかもしれない大きなコードブロックの 全体の時間を計測したいというような場合に便利です。

既に停止しているカウンタに対してtime-counter-stop!を呼んでも 何も起こりません。

Method: time-counter-reset! (counter <time-counter>)

カウンタcounterの値をリセットします。既にcounterが走っている 場合は、リセットの前にカウンタは停止させられます。

Method: time-counter-value (counter <time-counter>)

カウンタcounterの現在の値(秒数)を実数で返します。 分解能はそれぞれのカウンタが用いているシステムコールに依存します。

Macro: with-time-counter counter expr …

expr …が評価される間だけcounterを走らせる、 便利なマクロです。最後の式の結果を返します。このマクロは次のように 定義されます。

 
(define-syntax with-time-counter
  (syntax-rules ()
    ((_ counter . exprs)
     (dynamic-wind
      (lambda () (time-counter-start! counter))
      (lambda () . exprs)
      (lambda () (time-counter-stop! counter))))
    ))

下の例では、ループ内でのprocess-Aとprocess-Bにて費された 概略の時間をそれぞれ計測します。

 
(let ((ta (make <real-time-counter>))
      (tb (make <real-time-counter>)))
  (dotimes (i 100000)
    (with-time-counter ta
      (process-A))
    (with-time-counter tb
      (process-B)))
  (format #t "Time spent in process-A: ~s\n" (time-counter-value ta))
  (format #t "Time spent in process-B: ~s\n" (time-counter-value tb))
  )

[ < ] [ > ]   [ << ] [ Up ] [ >> ]

This document was generated by Shiro Kawai on November, 22 2009 using texi2html 1.78.