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 |
2010-02-10
KMRCLを眺める (84) COPY-BINARY-STREAM
Common Lisp, KMRCL | |
![]()
今回は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
やっぱり、それなりに速いみたいですね。
■
2010-02-08
KMRCLを眺める (83) WRITE-UTIME-YMDHM
Common Lisp, KMRCL | |
![]()
今回はKMRCLのio.lisp中からWRITE-UTIME-YMDHMです。
やっとこさ日付シリーズが終りです。
動作は
(WRITE-UTIME-YMDHM 0 :UTC-OFFSET 0) ;⇒ "1900/01/01 00:00"
で、定義は、
(defun write-utime-ymdhm (utime &key stream utc-offset)
(if stream
(write-utime-ymdhm-stream utime stream utc-offset)
(with-output-to-string (s)
(write-utime-ymdhm-stream utime s utc-offset))))
となっています。
文字ストリームに出力するか指定のストリームに出力するかをもっと簡潔に書けたりしないものかと考えましたが、いまいちこれといった書き方も見付からず。
■
2010-02-07
KMRCLを眺める (82) WRITE-UTIME-YMDHM-STREAM
Common Lisp, KMRCL | |
![]()
今回はKMRCLのio.lisp中からWRITE-UTIME-YMDHM-STREAMです。
名前が似たようなのが多いので、どこまで読んだのかを見失います…。
動作は
(WITH-OUTPUT-TO-STRING (OUT) (WRITE-UTIME-YMDHM-STREAM (GET-UNIVERSAL-TIME) OUT)) ;⇒ "2010/02/07 15:12"
で、前のWRITE-UTIME-YMDHMS-STREAMとは秒があるかないかの違いです。
定義は、
(defun write-utime-ymdhm-stream (utime stream &optional utc-offset)
(with-utime-decoding-utc-offset (utime utc-offset)
(write-string (prefixed-fixnum-string year nil 4) stream)
(write-char #\/ stream)
(write-string (aref +datetime-number-strings+ month) stream)
(write-char #\/ stream)
(write-string (aref +datetime-number-strings+ day-of-month) stream)
(write-char #\space stream)
(write-string (aref +datetime-number-strings+ hour) stream)
(write-char #\: stream)
(write-string (aref +datetime-number-strings+ minute) stream)))
となっています。
■
2010-02-06
KMRCLを眺める (81) WRITE-UTIME-YMDHMS
Common Lisp, KMRCL | |
![]()
今回はKMRCLのio.lisp中からWRITE-UTIME-YMDHMSです。
前回のWRITE-UTIME-YMDHMS-STREAMをWITH-OUTPUT-TO-STRINGで包んだものです。
(WRITE-UTIME-YMDHMS (GET-UNIVERSAL-TIME)) ;⇒ "2010/02/06 22:27:37"
定義は、
(defun write-utime-ymdhms (utime &key stream utc-offset)
(if stream
(write-utime-ymdhms-stream utime stream utc-offset)
(with-output-to-string (s)
(write-utime-ymdhms-stream utime s utc-offset))))
ちなみに、このパターンがもう何日か続きます…
■
2010-02-05
KMRCLを眺める (80) WRITE-UTIME-YMDHMS-STREAM
Common Lisp, KMRCL | |
![]()
今回はKMRCLのio.lisp中からWRITE-UTIME-YMDHM-STREAMです。
動作は
(WITH-OUTPUT-TO-STRING (OUT) (WRITE-UTIME-YMDHM-STREAM (GET-UNIVERSAL-TIME) OUT)) ;⇒ "2010/02/05 23:15:37"
というところです。割と良く使う形式かもしれません。
定義は、
(defun write-utime-ymdhms-stream (utime stream &optional utc-offset)
(with-utime-decoding-utc-offset (utime utc-offset)
(write-string (prefixed-fixnum-string year nil 4) stream)
(write-char #\/ stream)
(write-string (aref +datetime-number-strings+ month) stream)
(write-char #\/ stream)
(write-string (aref +datetime-number-strings+ day-of-month) stream)
(write-char #\space stream)
(write-string (aref +datetime-number-strings+ hour) stream)
(write-char #\: stream)
(write-string (aref +datetime-number-strings+ minute) stream)
(write-char #\: stream)
(write-string (aref +datetime-number-strings+ second) stream)))
となっていますが、この定義の中のPREFIXED-FIXNUM-STRINGは、string.lispで定義されていて、ここでは、0でパディングされた数字を出力するのに利用しているようです。
(PREFIXED-FIXNUM-STRING 77 NIL 8) ;⇒ "00000077"
どうもKMRCL(というかKMR氏)は、FORMATでがんばったりはあまりしないスタイルなのかなと思えてきました。
そういうスタイルもありですね。
■