Subject: Re: reading/writing bytes smaller than 8 bits?
From: Erik Naggum <erik@naggum.no>
Date: 2000/01/25
Newsgroups: comp.lang.lisp
Message-ID: <3157825117110563@naggum.no>

* "Bruce L. Lambert" <lambertb@uic.edu>
| When I write n (unsigned-byte 4)s to my file-system (solaris 2.6 on a
| sparc clone), and then I say ls -l to look at the size of the file, there
| are n bytes in the file rather than n/2 as I would have expected.

  why did you expect that?

| Does this mean the file system can write nothing smaller than an 8-bit
| byte?

  the file system has nothing to do with it.  Unix doesn't know about file
  contents at all, and as an operating system design, takes significant
  pride in that fact.

| If so, does this in any way affect what happens when I read an
| (unsigned-byte 4) from the same file.

  if you write (unsigned-byte 4) to a file and read it again, you should
  get the exact same values back.  how these bits are stored is none of
  your business.

  if your expectations can be defended and you have reason to use this
  feature to obtain improved storage performance, talk with your CL vendor
  and have them make it work for you.

| I've played with this some, and the values appear to be correct, but I'm
| still wondering what's happening 'below the surface'.

  the only people who can really answer that question is the person who
  implemented the feature in your Common Lisp implementation.  finding that
  person may be hard, but if you use free software, the source is there.
  if not, you should use the customer support facilities of the vendor.

| Is it still the case that an array of n 4-bit bytes will occupy (roughly)
| n/2 bytes of main memory when loaded into lisp?

  if it makes performance sense to do so, or people have argued for this
  feature even if it didn't, it will.  you can, however, easily measure the
  space costs of an allocation.  for instance,

(time (make-array 1000 :element-type '(unsigned-byte 4) :initial-element 0))
; cpu time (non-gc) 0 msec user, 0 msec system
; cpu time (gc)     0 msec user, 0 msec system
; cpu time (total)  0 msec user, 0 msec system
; real time  14 msec
; space allocation:
;  9 cons cells, 0 symbols, 512 other bytes, 0 static bytes
=> #(0 0 0 0 0 0 0 0 0 0 ...)
(4) cl-user
(time (make-array 1000 :element-type '(unsigned-byte 8) :initial-element 0))
; cpu time (non-gc) 0 msec user, 0 msec system
; cpu time (gc)     0 msec user, 0 msec system
; cpu time (total)  0 msec user, 0 msec system
; real time  0 msec
; space allocation:
;  9 cons cells, 0 symbols, 1,016 other bytes, 0 static bytes
=> #(0 0 0 0 0 0 0 0 0 0 ...)
(5) cl-user
(time (make-array 1000 :element-type '(unsigned-byte 2) :initial-element 0))
; cpu time (non-gc) 0 msec user, 0 msec system
; cpu time (gc)     0 msec user, 0 msec system
; cpu time (total)  0 msec user, 0 msec system
; real time  0 msec
; space allocation:
;  9 cons cells, 0 symbols, 512 other bytes, 0 static bytes
=> #(0 0 0 0 0 0 0 0 0 0 ...)
(6) cl-user
(time (make-array 1000 :element-type '(unsigned-byte 1) :initial-element 0))
; cpu time (non-gc) 0 msec user, 0 msec system
; cpu time (gc)     0 msec user, 0 msec system
; cpu time (total)  0 msec user, 0 msec system
; real time  0 msec
; space allocation:
;  9 cons cells, 0 symbols, 144 other bytes, 0 static bytes
=> #*0000000000.. ; [abbreviated by me]
(7) cl-user
(time (make-array 1000 :element-type '(unsigned-byte 16) :initial-element 0))
; cpu time (non-gc) 0 msec user, 0 msec system
; cpu time (gc)     0 msec user, 0 msec system
; cpu time (total)  0 msec user, 0 msec system
; real time  0 msec
; space allocation:
;  9 cons cells, 0 symbols, 2,016 other bytes, 0 static bytes
=> #(0 0 0 0 0 0 0 0 0 0 ...)

  the reported results show the storage strategies and optimizations for
  various data types.

#:Erik