From: Stefan L. <lan...@gm...> - 2007-01-17 22:33:30
Attachments:
seq.lisp.diff
|
Hi, I noticed (and apparently someone else on comp.lang.lisp, too) that concatenate could be a lot faster, at least for simple-array types. Personally, I use concatenate mostly with two or three simple-string arguments and with 'string as result type. Grepping through the various CL libraries I have lying around, it seems that this is really the most common use case (say >= 3/4). So I've created specialized concat-simple-string2 and concate-simple-string3 functions and a compiler macro for concatenate that converts certain calls to concatenate to concatenate-simple-string2 or concatenate-simple-string3. I've checked and Allegro also has a compiler macro for concatenate. It gives me a speedup of about an order of magnitude. The patch should be attached. Sbcl builds and tests pass with it. Would be nice if this or something similar in effect would make it into CVS. Some (time ...) before/after comparisons: CL-USER> (defparameter *s1* (make-string 100 :initial-element #\a)) *S1* CL-USER> (defparameter *s2* (make-string 100 :initial-element #\b)) *S2* CL-USER> (defparameter *s3* (make-string 100 :initial-element #\c)) *S3* CL-USER> (defparameter *v* nil) *V* ;;; Before CL-USER> (time (loop repeat 1000000 do (setf *v* (concatenate 'string "a" "b")))) Evaluation took: 2.187 seconds of real time 2.160135 seconds of user run time 0.008001 seconds of system run time [Run times include 0.124 seconds GC run time.] 0 calls to %EVAL 0 page faults and 111,998,504 bytes consed. NIL ;;; After CL-USER> (time (loop repeat 1000000 do (setf *v* (concatenate 'string "a" "b")))) Evaluation took: 0.143 seconds of real time 0.144009 seconds of user run time 0.0 seconds of system run time [Run times include 0.02 seconds GC run time.] 0 calls to %EVAL 0 page faults and 24,004,280 bytes consed. NIL ;;; Before CL-USER> (time (loop repeat 1000000 do (setf *v* (concatenate 'string "a" "b" "c")))) Evaluation took: 2.438 seconds of real time 2.372148 seconds of user run time 0.008 seconds of system run time [Run times include 0.092 seconds GC run time.] 0 calls to %EVAL 0 page faults and 152,000,736 bytes consed. NIL ;;; After CL-USER> (time (loop repeat 1000000 do (setf *v* (concatenate 'string "a" "b" "c")))) Evaluation took: 0.2 seconds of real time 0.196013 seconds of user run time 0.0 seconds of system run time [Run times include 0.032 seconds GC run time.] 0 calls to %EVAL 0 page faults and 24,004,824 bytes consed. NIL ;;; Before CL-USER> (time (loop repeat 1000000 do (setf *v* (concatenate 'string *s1* *s2*)))) Evaluation took: 25.206 seconds of real time 24.94156 seconds of user run time 0.024002 seconds of system run time [Run times include 0.452 seconds GC run time.] 0 calls to %EVAL 0 page faults and 903,957,528 bytes consed. NIL ;;; After CL-USER> (time (loop repeat 1000000 do (setf *v* (concatenate 'string *s1* *s2*)))) Evaluation took: 2.044 seconds of real time 2.028127 seconds of user run time 0.016001 seconds of system run time [Run times include 0.5 seconds GC run time.] 0 calls to %EVAL 0 page faults and 815,950,896 bytes consed. NIL ;;; Before CL-USER> (time (loop repeat 1000000 do (setf *v* (concatenate 'string *s1* *s2* *s3*)))) Evaluation took: 37.812 seconds of real time 36.366272 seconds of user run time 0.056004 seconds of system run time [Run times include 0.72 seconds GC run time.] 0 calls to %EVAL 0 page faults and 1,343,888,536 bytes consed. NIL ;;; After CL-USER> (time (loop repeat 1000000 do (setf *v* (concatenate 'string *s1* *s2* *s3*)))) Evaluation took: 3.44 seconds of real time 3.404213 seconds of user run time 0.020001 seconds of system run time [Run times include 0.744 seconds GC run time.] 0 calls to %EVAL 0 page faults and 1,215,885,088 bytes consed. NIL Stefan |