While playing around with optimizations and time on cmucl and sbcl I ran
into some things I don't quite understand. Both questions are at the
bottom of this post after some introductory information.
The function I was playing around with is this:
==========
(defun string* (count string)
(declare (optimize (speed 3) (safety 0) (debug 0) (compilation-speed 0))
(type fixnum count)
(type string string))
(let ((new-string (make-array (* count (length string))
:element-type 'character :fill-pointer 0)))
(with-output-to-string (stream new-string)
(dotimes (unused-index count)
(write-string string stream)))
new-string))
==========
Which lets you do (string* 3 "foo") and get "foofoofoo".
My first question has to do with the compiler notes issued by cmucl and
sbcl. cmucl issues a note regarding (length string):
==========
; In: DEFUN STRING*
; (LENGTH STRING)
; ==>
; (C::VECTOR-LENGTH VECTOR)
; Note: Unable to optimize due to type uncertainty:
; The first argument is a BASE-STRING, not a (SIMPLE-ARRAY * (*)).
==========
sbcl issues a note regarding the multiplication:
==========
; in: DEFUN STRING*
; (* COUNT (LENGTH STRING))
;
; note: forced to do GENERIC-* (cost 30)
; unable to do inline fixnum arithmetic (cost 4) because:
; The result is a (VALUES (INTEGER -288230375077969920
; 288230374541099010)
; &OPTIONAL), not a (VALUES FIXNUM &REST T).
; unable to do inline (signed-byte 32) arithmetic (cost 5) because:
; The result is a (VALUES (INTEGER -288230375077969920
; 288230374541099010)
; &OPTIONAL), not a (VALUES (SIGNED-BYTE 32)
; &REST
; T).
==========
Question 1: How do you make these go away and would you want to if you
could?
My next question is regarding the output of:
(time (defparameter *foo* (string* 1000000 "0123456789")))
On my hardware this takes about 0.25 seconds for both cmucl and
sbcl. However, cmucl tells me I have "10,000,168 bytes consed" while sbcl
tells me I have "40,000,016 bytes consed".
Question 2: Is this difference because sbcl supports unicode and cmucl
doesn't or is there another reason?
Thanks for any replies.
+ John <········@mailinator.com>:
| (defun string* (count string)
| (declare (optimize (speed 3) (safety 0) (debug 0) (compilation-speed 0))
| (type fixnum count)
| (type string string))
| (let ((new-string (make-array (* count (length string))
| :element-type 'character :fill-pointer 0)))
| (with-output-to-string (stream new-string)
| (dotimes (unused-index count)
| (write-string string stream)))
| new-string))
|
| sbcl issues a note regarding the multiplication:
|
| ==========
|
| ; in: DEFUN STRING*
| ; (* COUNT (LENGTH STRING))
| ;
| ; note: forced to do GENERIC-* (cost 30)
| ; unable to do inline fixnum arithmetic (cost 4) because:
| ; The result is a (VALUES (INTEGER -288230375077969920
| ; 288230374541099010)
| ; &OPTIONAL), not a (VALUES FIXNUM &REST T).
| ; unable to do inline (signed-byte 32) arithmetic (cost 5) because:
| ==========
|
| Question 1: How do you make these go away and would you want to if you
| could?
For the sbcl note, just wrap an inline declaration around the product
like this:
(the (signed-byte 32) (* count (length string)))
I trust others will comment on the cmucl note.
--
* Harald Hanche-Olsen <URL:http://www.math.ntnu.no/~hanche/>
- Debating gives most of us much more psychological satisfaction
than thinking does: but it deprives us of whatever chance there is
of getting closer to the truth. -- C.P. Snow
Hello,
John <········@mailinator.com> writes:
> While playing around with optimizations and time on cmucl and sbcl I ran
> into some things I don't quite understand. Both questions are at the
> bottom of this post after some introductory information.
[deletia]
> My next question is regarding the output of:
>
> (time (defparameter *foo* (string* 1000000 "0123456789")))
>
> On my hardware this takes about 0.25 seconds for both cmucl and
> sbcl. However, cmucl tells me I have "10,000,168 bytes consed" while sbcl
> tells me I have "40,000,016 bytes consed".
>
> Question 2: Is this difference because sbcl supports unicode and cmucl
> doesn't or is there another reason?
Yes: in an unicode-enabled SBCL, "full" characters are 21 bits and
require 32 bits of storage. Christophe exposed all the juicy details
during its Amsterdam talk:
http://www.doc.gold.ac.uk/~mas01cr/talks/2005-04-24%20Amsterdam/presentation.pdf
> Thanks for any replies.
Cu,
Damien.
--
http://foobox.net/~dash/
I can resist everything except temptation.
--Oscar Wilde
On 9212 day of my life ········@mailinator.com wrote:
> On my hardware this takes about 0.25 seconds for both cmucl and
> sbcl. However, cmucl tells me I have "10,000,168 bytes consed" while sbcl
> tells me I have "40,000,016 bytes consed".
Do you have SBCL with Unicode support? If so, each character is 4
bytes in Unicode-SBCL and 1 byte in CMU CL.
--
Ivan Boldyrev
XML -- new language of ML family.