Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2009-12-20

KMRCLを眺める (43) MAPCAR-APPEND-STRING-NONTAILREC

| 02:45 | KMRCLを眺める (43) MAPCAR-APPEND-STRING-NONTAILREC - わだばLisperになる を含むブックマーク はてなブックマーク - KMRCLを眺める (43) MAPCAR-APPEND-STRING-NONTAILREC - わだばLisperになる

今回は、KMRCLのlists.lisp中からMAPCAR-APPEND-STRING-NONTAILRECです。

名前からするに、MAPCARしつつ、結果を文字列として合体する関数でいて末尾再帰ではない実装という感じです。

定義は、

(defun mapcar-append-string-nontailrec (func v)
  "Concatenate results of mapcar lambda calls"
  (aif (car v)
       (concatenate 'string (funcall func it)
                    (mapcar-append-string-nontailrec func (cdr v)))
       ""))

こんな感じで、CONCATENATEで文字をつなげていて、AIFが上手く使われています。

動作は、

(MAPCAR-APPEND-STRING-NONTAILREC #'STRING-UPCASE 
                                 '("foo" "bar" "baz"))
⇒ "FOOBARBAZ"

という感じです。

実装を見たところそんなに効率を追求している風にも見えないし、FORMATで文字列をつなげても、そんなに速度は変わらないんじゃないかなあ、と思い実験してみたところ、およそ10倍弱の差でMAPCAR-APPEND-STRING-NONTAILRECが速いという結果が出ました。

MAPCAR-APPEND-STRING-NONTAILRECが割と速いというべきか、思ったよりFORMATが遅いというべきか…。

(LOOP :REPEAT 100000
      :DO (MAPCAR-APPEND-STRING-NONTAILREC #'VALUES 
                                           '("foo" "bar" "baz")))
;⇒ NIL
----------
Evaluation took:
  0.127 seconds of real time
  0.130000 seconds of total run time (0.130000 user, 0.000000 system)
  [ Run times consist of 0.010 seconds GC time, and 0.120 seconds non-GC time. ]
  102.36% CPU
  304,275,915 processor cycles
  38,418,352 bytes consed
  
Intel(R) Core(TM)2 Duo CPU     P8600  @ 2.40GHz
(LOOP :REPEAT 100000
      :DO (FORMAT NIL "~{~A~}" '("foo" "bar" "baz")))
;⇒ NIL
----------
Evaluation took:
  1.028 seconds of real time
  1.020000 seconds of total run time (1.000000 user, 0.020000 system)
  [ Run times consist of 0.340 seconds GC time, and 0.680 seconds non-GC time. ]
  99.22% CPU
  2,460,705,210 processor cycles
  633,721,168 bytes consed
  
Intel(R) Core(TM)2 Duo CPU     P8600  @ 2.40GHz