andとifの比較とか

 最近時々ifをandで書いたりすることがあって、見やすくていいんだけど、速度はどういう感じなのかとか思ってみたりした話。
 まず、andでifの代わりをする話は、具体的に、こういう感じ

(setq foo 1 bar 2)

(and foo bar)
=>2
(if foo bar)
=>2

こういう感じに書くと、(and foo bar)は大体(if foo bar)と同じように動く。で、見やすいので時々使うといったのは、何となくコレで置き換えたりする時も在るけど、ネストするとandの方が見やすい感じ。

(if foo
	(if bar
		(if foo
			bar)))
(and foo ba foo bar)

 こういう感じ、でもほぼ等価の動きなので。しかし、見やすくても速度のは違うのかなぁとか、思ったりして調べてみた。ら100倍くらい違った。

(let ((st (si:performance-counter)))
  (if foo bar)
  (format nil "~A" (-(si:performance-counter) st))

 こういう感じで、(if foo bar)と(and foo bar)を置き換えて調査。勿論ifが凄く高速なので100倍違うってもandが致命的に遅いわけじゃないけど。andはマクロなので、バイトコンパイルすると高速になりそうだし大した問題じゃないのかもしれない。マクロの中身を確認してみると。

(macroexpand '(and foo bar))
=>(if foo bar)

と言う感じで、お互いに全く等価なのでバイトコンパイルすれば速度は同じになりそう。

■以下は何となく興味本位の追記

  • andでifの条件を書くべきかandだけで書いてしまうかとか
(setq A t B t C 1)
(if (and A B) C)
=>1

(and A B C)
=>1

(macroexpand '(and A B C))
=> (if A (if B C))

(macroexpand '(and A B))
=>(if A B)