Skip to content

compute-size should probably not include the size of RTDs #968

@dpk

Description

@dpk

The result of compute-size appears to include the size of RTDs for user-defined records, but not the sizes of the record types that are used to implement the types which come with Chez Scheme. This is at least confusing to the implementers of alternative data structure implementations, and at worst unfair since it may give users a misleading impression that these alternative implementations are significantly worse in terms of the memory usage of each instance than the Chez Scheme types, even if the memory usage is actually better.

A concrete example: I was curious how the memory usage of my sample implementation of SRFI 250 stacked up against the standard Chez Scheme R6RS hashtable implementation.

The code used to create the hash tables for comparison
(define srfi-250-alphabet-table
        (hash-table-unfold (lambda (c) (char>? c #\z))
                           (lambda (c) (values c (char-upcase c)))
                           (lambda (c) (integer->char (+ 1 (char->integer c))))
                           #\a
                           (make-comparator char? char=? #f (lambda (c) (number-hash (char->integer c))))
                           26))

(define r6rs-alphabet-table
    (let ((ht (make-hashtable (lambda (c) (number-hash (char->integer c))) char=? 26)))
      (let loop ((a 97))
        (if (> a 122)
            ht
            (begin
              (hashtable-set! ht (integer->char a) (char-upcase (integer->char a)))
              (loop (+ a 1)))))))
> (compute-size r6rs-alphabet-table)
1184
> (compute-size srfi-250-alphabet-table)
1006832

It really puzzled me why this small 26-entry hash table was taking up so much more memory in my implementation than in the Chez one: over a megabyte! Moreover, the inspector was not much help because I had made the hash-table type from SRFI 250 opaque, so I could not see the individual fields there to compute their respective sizes and see where the bloat was coming from.

After changing the definition to be transparent, I went back into the inspector and totted up the size results on each of the fields, all of which were small as I expected. Only then did it occur to me to check the size on the rtd: it weighs 1006240 bytes all on its own! Subtracting its weight (outside of Chez Scheme) gives the far more reasonable answer 592. Cool, my implementation is 50% more memory-efficient for this hash table! But it is a problem that my more memory-efficient implementation appears vastly more bloated, because the implementation of the built-in type ‘cheats’ by automatically not counting the size of the RTD.

I also think it is especially a problem, in cases like this, that there is no way to find out how much the RTD weighs according to compute-size if the record type is opaque. I think record types used as encapsulation for generic data structure implementations (rather than as domain-specific ‘plain old data objects’) should be opaque as a matter of course, since their implementation details should not bother the user of the data structure and they should not be tempted to extract information from it. (The Chez Scheme developers may disagree, since the built-in hash tables are not opaque!)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions