-
Notifications
You must be signed in to change notification settings - Fork 27
Description
Hi folks,
I'm working on a toy project that involves encoding/decoding some binary data, and I happened to notice that using flexi-streams' in-memory streams is much much slower vs. reading/writing from a binary file. Just wondering if there is any reason for this weirdness. Here is a simple test function (it'll output like 50M into a file in /tmp/).
(ql:quickload '("trivial-utf-8" "flexi-streams"))
(defmacro mytime (title &body body)
`(progn
(format t "Timing: ~A~%" ,title)
(time ,@body)))
(defun test-flexi-streams (&optional (filename "/tmp/flexistreams.bin"))
(let* ((str "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ăşţîâĂŞŢÎÂ")
(size (trivial-utf-8:utf-8-byte-length str))
(times 500000)
(sequence))
(mytime "write to built-in stream"
(with-open-file (output filename :element-type '(unsigned-byte 8)
:direction :output
:if-does-not-exist :create
:if-exists :supersede)
(loop repeat times
do (trivial-utf-8:write-utf-8-bytes str output))))
(mytime "write to flexi in-memory stream"
(let ((output (flexi-streams:make-in-memory-output-stream)))
(loop repeat times
do (trivial-utf-8:write-utf-8-bytes str output))
(setf sequence (flexi-streams:get-output-stream-sequence output))))
(mytime "read from built-in stream"
(with-open-file (input filename :element-type '(unsigned-byte 8))
(loop repeat times
do (trivial-utf-8:read-utf-8-string input :byte-length size))))
(mytime "read from in-memory stream"
(let ((input (flexi-streams:make-in-memory-input-stream sequence)))
(loop repeat times
do (trivial-utf-8:read-utf-8-string input :byte-length size))))))Results here look like this:
Timing: write to built-in stream
Evaluation took:
0.336 seconds of real time
0.334568 seconds of total run time (0.291399 user, 0.043169 system)
99.70% CPU
601,427,574 processor cycles
0 bytes consed
Timing: write to flexi in-memory stream
Evaluation took:
2.256 seconds of real time
2.256795 seconds of total run time (2.256746 user, 0.000049 system)
[ Real times consist of 0.003 seconds GC time, and 2.253 seconds non-GC time. ]
[ Run times consist of 0.001 seconds GC time, and 2.256 seconds non-GC time. ]
100.04% CPU
4,058,053,884 processor cycles
134,180,240 bytes consed
Timing: read from built-in stream
Evaluation took:
0.566 seconds of real time
0.567083 seconds of total run time (0.543763 user, 0.023320 system)
[ Real times consist of 0.003 seconds GC time, and 0.563 seconds non-GC time. ]
[ Run times consist of 0.001 seconds GC time, and 0.567 seconds non-GC time. ]
100.18% CPU
1,019,238,246 processor cycles
448,008,624 bytes consed
Timing: read from in-memory stream
Evaluation took:
3.040 seconds of real time
3.033796 seconds of total run time (3.027243 user, 0.006553 system)
[ Real times consist of 0.003 seconds GC time, and 3.037 seconds non-GC time. ]
[ Run times consist of 0.001 seconds GC time, and 3.033 seconds non-GC time. ]
99.80% CPU
5,456,326,518 processor cycles
447,991,600 bytes consed
I'm using SBCL 2.3.9.63-23c796775.
I'm not sure something can be done about it, but if it's possible to improve, I guess a lot of projects will benefit. In my case I'm forced to ditch flexi-streams for now; the difference is so big that if I have the data in memory, I'm better off dumping it into a file and read it back from there, rather than going through in-memory-input-stream.