#;(time (read-data reader (cadr args)))
; real 38.053
; user 34.980
; sys 1.350
;(time (read-data kaizou:reader (cadr args)))
; real 31.884
; user 29.660
; sys 0.860
csvのreverseをreverse!にしただけですが、ちょっと早くなりました。
#(define (quoted-tail fields)
(let loop ([ch (read-char)])
(cond [(eor? ch) (reverse fields)]
[(eq? ch sep) (start fields)] ; <----- ここなんですが
[else (loop (read-char))])))
セパレータをeq?で見ているのですが、これはバグ?
#すごい‼ そんなのよく気付きましたね。
#R5RS 的には文字 eq? での文字比較結果は未定義になってますが、 gauche.h のコメントを読んでみると Gauche では eq? で比較可能っぽく読めるので、動作として問題にはならないと思います。 速度のことを考えると eqv? で比較するよりちょっと有利なんじゃないですかね。 意図的なものかどうかはわかりませんが…。
#src/boolean.c を見ると、if (SCM_NUMBERP(x))の分だけ速くなるわけですが、このquoted-tailのところだけeq?になっているからバグ(というかtypo?)かと思うのです。
#ああ、それはtypoです。eqv?を意図してます。確かにeq?の方が速いですが、多分そんなに差は出ないと思います。
#csvのfield加算をqueueで書いて見ました。reverseをreverse!にしたときとあまりかわらない性能ではありました。 https://gist.github.com/yamasushi/5696605 #強いて言えば、コードの見通しが少し良くなったような気がするくらいです。(schemeになれないのでconsがつづくと混乱するのです。^^;)
#まあ性能的にはreverse!とほとんど変わらないでしょうね。使うコンスセル数は同じで、queueの方はキューのアロケートコストがかかるけどreverse!の方は最後にトラバースするコストがかかるから相殺ってとこかな (この理屈だと、1レコードのフィールド数が少なければreverse!の方が有利、むちゃくちゃ多ければqueueの方が有利になると予想される)。コードとしては、私は隠れた状態がなるべく無い方(reverse!)を好みます。まあ面倒くさくなると
#状態のあるコードを書いちゃうことも多いけど。
#なるほど。このcsvの件は勉強になります。