From: John
Subject: compiler notes and bytes consed
Date: 
Message-ID: <slrndgpjl1.2mhq.saioCB1l@mailinator.com>
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.

From: Harald Hanche-Olsen
Subject: Re: compiler notes and bytes consed
Date: 
Message-ID: <pcok6ibt872.fsf@shuttle.math.ntnu.no>
+ 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
From: Damien Diederen
Subject: Re: compiler notes and bytes consed
Date: 
Message-ID: <87slwzjcpg.fsf@keem.bcc>
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
From: Ivan Boldyrev
Subject: Re: compiler notes and bytes consed
Date: 
Message-ID: <fvpvt2-5mp.ln1@ibhome.cgitftp.uiggm.nsc.ru>
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.