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 |

2010-02-10

KMRCLを眺める (84) COPY-BINARY-STREAM

| 00:13 | KMRCLを眺める (84) COPY-BINARY-STREAM - わだばLisperになる を含むブックマーク はてなブックマーク - KMRCLを眺める (84) COPY-BINARY-STREAM - わだばLisperになる

今回はKMRCLのio.lisp中からCOPY-BINARY-STREAMです。

動作は

(WITH-OPEN-FILE (IN "/usr/share/dict/words" :ELEMENT-TYPE '(UNSIGNED-BYTE 8))
  (WITH-OPEN-FILE (OUT "/tmp/k.txt" :DIRECTION :OUTPUT
                                    :IF-EXISTS :SUPERSEDE 
                                    :IF-DOES-NOT-EXIST :CREATE)
    (COPY-BINARY-STREAM IN OUT)))
;⇒ NIL
;; /tmp/k.txtに/usr/share/dict/wordsと同じ内容のファイルができる

というところでしょうか。

定義は、

(defun copy-binary-stream (in out &key (chunk-size 16384))
  (do* ((buf (make-array chunk-size :element-type '(unsigned-byte 8)))
        (pos (read-sequence buf in) (read-sequence buf in)))
      ((zerop pos))
    (write-sequence buf out :end pos)))

となっています。

まとめてチャンクで読み書きしているのは、きっとこの方が速くなるからだろう、ということで計測してみました。

;; COPY-BINARY-STREAM利用
(LOOP :REPEAT 100 
      :DO (WITH-OPEN-FILE (IN "/usr/share/dict/words" :ELEMENT-TYPE '(UNSIGNED-BYTE 8))
            (WITH-OPEN-FILE (OUT "/tmp/k.txt" :DIRECTION :OUTPUT
                                 :IF-EXISTS :SUPERSEDE 
                                 :IF-DOES-NOT-EXIST :CREATE
                                 :ELEMENT-TYPE '(UNSIGNED-BYTE 8))
              (COPY-BINARY-STREAM IN OUT))))
;⇒ NIL
;----------
; cpu time (non-gc) 0.070000 sec user, 0.750000 sec system
; cpu time (gc)     0.000000 sec user, 0.000000 sec system
; cpu time (total)  0.070000 sec user, 0.750000 sec system
; real time  2.299199 sec
; space allocation:
;  11,815 cons cells, 2,450,064 other bytes, 0 static bytes

;; READ-BYTEしてWRITE-BYTE
(LOOP :REPEAT 100 
      :DO (WITH-OPEN-FILE (IN "/usr/share/dict/words" :ELEMENT-TYPE '(UNSIGNED-BYTE 8))
            (WITH-OPEN-FILE (OUT "/tmp/k.txt" :DIRECTION :OUTPUT
                                              :IF-EXISTS :SUPERSEDE 
                                              :IF-DOES-NOT-EXIST :CREATE
                                              :ELEMENT-TYPE '(UNSIGNED-BYTE 8))
              (LOOP :FOR B := (READ-BYTE IN NIL -1) :UNTIL (MINUSP B)
                    :DO (WRITE-BYTE B OUT)))))

;⇒ NIL
;----------
; cpu time (non-gc) 5.040000 sec user, 0.750000 sec system
; cpu time (gc)     0.000000 sec user, 0.000000 sec system
; cpu time (total)  5.040000 sec user, 0.750000 sec system
; real time  6.685070 sec
; space allocation:
;  17,645 cons cells, 430,736 other bytes, 0 static bytes

やっぱり、それなりに速いみたいですね。