2014-02-20-01-ファンクタの悩み - 2
>> Site top >> weblog >> 月別アーカイブ >> 2014年02月のlog >> 2014-02-20-01-ファンクタの悩み - 2
最終更新日付:2014/02/20 01:00:00
ファンクタの悩み - 2
2014 年 02 月 20 日
前回からの続き。
とりあえず、ファンクタの値渡しを模倣するために CLOS の使用を模索し始めた。今回は、ちょっと心配なパフォーマンスを調べてみようという話。
まぁ自分から見れば Lisp はまだ外国語なので、何が効率が良いのかとかは試してみないとわからない。そんなわけで、試しに動かしてみましょうということで書いたのが以下のコード。まずは比較のための関数版。単純にパラメータを2倍する。
(locally (declare (optimize speed)) (defun foo-function (n) (declare (type fixnum n)) (the fixnum (* 2 n))))
で、以下が同じことをするファンクタ版。functor-copy が実際にはコピーを作成していないが、これは foo-functor が状態を持たないからだ。
(defclass foo-functor () ()) (defmethod functor-copy ((func foo-functor)) func) (locally (declare (optimize speed)) (defmethod unary-function ((func foo-functor) arg) (declare (type fixnum arg)) (the fixnum (* 2 arg))))
これらを指定した回数だけコールするための2つの関数を用意する。
(locally (declare (optimize speed)) (defun func-invoke-test (fnc n) (declare (type fixnum n)) (do ((i 0 (incf i))) ((<= n i) nil) (declare (type fixnum i)) (funcall fnc i)))) (locally (declare (optimize speed)) (defun method-invoke-test (fnc n) (declare (type fixnum n)) (do ((i 0 (incf i))) ((<= n i) nil) (declare (type fixnum i)) (functor-invoke fnc i))))
で、これらをそれぞれ1億回ずつコールしてみるわけだ。関数の直接コールと、functor-invoke 経由での関数コール、そして functor-invoke 経由でのファンクタコールの3種類だ。
(let ((count 100000000)) (time (func-invoke-test #'foo-function count)) (time (method-invoke-test #'foo-function count)) (time (method-invoke-test (make-instance 'foo-functor) count)))
実行したのは Windows 版の SBCL 64bit 環境。結果は以下のとおり。
Evaluation took: 0.873 seconds of real time 0.858006 seconds of total run time (0.858006 user, 0.000000 system) 98.28% CPU 2,081,088,036 processor cycles 0 bytes consed Evaluation took: 1.779 seconds of real time 1.778412 seconds of total run time (1.778412 user, 0.000000 system) 99.94% CPU 4,273,856,574 processor cycles 0 bytes consed Evaluation took: 1.342 seconds of real time 1.341609 seconds of total run time (1.341609 user, 0.000000 system) 100.00% CPU 3,224,172,645 processor cycles 0 bytes consed
なんとまぁ、関数コールの方が速いのは予想通りだが、functor-invoke も思ったほど遅くはない。それよりなにより、同じ functor-invoke ではクラスインスタンスの方が関数コールよりも速いではないの。これは予想外だった。
‥‥‥続きは(あれば)次回以降。
コメント
このページのタグ
Page tag : STLとその移植
Copyright(C) 2005-2021 project-enigma.
Generated by CL-PREFAB.