This patch causes a notable drop in output performance, since OUT-SYNONYM-OF is called quite a lot -- often needlessly -- and OUTPUT-STREAM-P is a generic function.
While I agree that this patch is in principle a good thing, other code needs to change as well for this to go in.
As an example:
(defun rush (stream n object)
(declare (fixnum n))
(loop repeat n
do (print object stream)))
Without the patch this runs in under 3.9 seconds run-time and 4.2 real-time on my system. With the patch it takes 6.4 seconds run-time and 6.6 seconds real-time.
-- like WRITE-CHAR, but doesn't deal with output stream designators -- and changing PRINT to
(defun print (object &optional stream)
#!+sb-doc
"Output a newline, the mostly READable printed representation of OBJECT, and
space to the specified STREAM."
(let ((stream (out-synonym-of stream)) (*print-escape* t))
(%write-char #\newline stream)
(output-object object stream)
(%write-char #\space stream)
object))
and similarly using %WRITE-CHAR instead of WRITE-CHAR in %OUTPUT-REASONABLE-INTEGER-IN-BASE makes the test-case run in 4.0 run-time and 4.3 real-time -- which is an acceptable cost, IMO.
So, all output functions underneath the user-callable layer need to be audited so that OUT-SYNONYM-OF is not called uselessly, instead of using WRITE-CHAR/STRING/WHATEVER using corresponding %WRITE-FOO functions which need to be written.
This patch causes a notable drop in output performance, since OUT-SYNONYM-OF is called quite a lot -- often needlessly -- and OUTPUT-STREAM-P is a generic function.
While I agree that this patch is in principle a good thing, other code needs to change as well for this to go in.
As an example:
(defun rush (stream n object)
(declare (fixnum n))
(loop repeat n
do (print object stream)))
(with-open-file (f "/tmp/rush.tmp" :if-exists :supersede :direction :output)
(time (rush f 10000000 42)))
Without the patch this runs in under 3.9 seconds run-time and 4.2 real-time on my system. With the patch it takes 6.4 seconds run-time and 6.6 seconds real-time.
Adding
(defun %write-char (character stream) out-stream/ no-synonym stream stream- out character) write-char character)))
(with-
(ansi-
(stream-
-- like WRITE-CHAR, but doesn't deal with output stream designators -- and changing PRINT to
(defun print (object &optional stream)
(*print- escape* t))
#!+sb-doc
"Output a newline, the mostly READable printed representation of OBJECT, and
space to the specified STREAM."
(let ((stream (out-synonym-of stream))
(%write-char #\newline stream)
(output-object object stream)
(%write-char #\space stream)
object))
and similarly using %WRITE-CHAR instead of WRITE-CHAR in %OUTPUT- REASONABLE- INTEGER- IN-BASE makes the test-case run in 4.0 run-time and 4.3 real-time -- which is an acceptable cost, IMO.
So, all output functions underneath the user-callable layer need to be audited so that OUT-SYNONYM-OF is not called uselessly, instead of using WRITE-CHAR/ STRING/ WHATEVER using corresponding %WRITE-FOO functions which need to be written.