NULLストリームを使う


Tag: 入出力

UNIXで言うところの/dev/nullのようなビットバケツ(ビットシンク)を実現するには、様々な方法があります。

自作する

自作の場合は、読み込みでEOFを返すのにmake-concatenated-streamや、make-string-input-streamに""の引数を与えたもの、出力にはmake-broadcast-streamを利用し作成することが多いようです。 処理系に依存しませんので最も可搬性が高い方法になります。

(defvar *null-stream* (make-two-way-stream 
                        (make-concatenated-stream) 
                        (make-broadcast-stream)))
(time
 (loop :repeat 10000 
       :do
       (format *null-stream* "こんにちは!")
       (read *null-stream* nil :eof)))
;-> cpu time (non-gc) 180 msec user, 0 msec system
;   cpu time (gc)     0 msec user, 0 msec system
;   cpu time (total)  180 msec user, 0 msec system
;   real time  187 msec
;   space allocation:
;    230,354 cons cells, 271,024 other bytes, 0 static bytes
;=> NIL

;; 他に
(make-two-way-stream (make-string-input-stream "")
                     (make-broadcast-stream))

処理系備え付けを利用する

処理系によっては、ビットバケツを用意している場合があります。Allegro CLのexcl::*null-stream*等。

下記では、simple-streamなどでNULLストリームを作成しています。

(let ((null-stream 
       #+LispWorks (make-instance 'stream::null-stream)
       #+Allegro (make-instance 'stream::null-stream)
       #+sbcl (make-instance 'sb-simple-streams:null-simple-stream)
       ))
 (time
  (loop :repeat 10000 
        :do
        (format null-stream "こんにちは!")
        (read null-stream nil :eof))))

UNIXの/dev/nullを利用する

UNIX限定となりますが、下記のようなものを利用する場合もあるようです

(defvar *null-stream* 
        (open #p"/dev/null" :direction :output :if-exists :overwrite))

ライブラリを利用する

CLiki:KMRCLにはnull-output-streamがありますが、UNIXの/dev/nullを利用する実装になっています。

議論