NAME

Devel::Size::Report - generate a size report for all elements in a structure

SYNOPSIS

        use Devel::Size::Report qw/report_size/;

        my $a = [ \8, \*STDIN, 7,
                  [ 1, 2, 3,
                    { a => 'b',
                      size => 12.2,
                      h => ['a']
                    },
                  'rrr'
                  ]
                ];
        print report_size($a, { indent => "  " } );

This will print something like this:

        Size report v0.08 for 'ARRAY(0x8145e6c)':
          Array 886 bytes (overhead: 100 bytes, 11.29%)
            Scalar Ref 32 bytes (overhead: 16 bytes, 50.00%)
              Read-Only Scalar 16 bytes
            Glob 266 bytes
            Scalar 16 bytes
            Array 472 bytes (overhead: 88 bytes, 18.64%)
              Scalar 16 bytes
              Scalar 16 bytes
              Scalar 16 bytes
              Hash 308 bytes (overhead: 180 bytes, 58.44%)
                'h' => Array 82 bytes (overhead: 56 bytes, 68.29%)
                  Scalar 26 bytes
                'a' => Scalar 26 bytes
                'size' => Scalar 20 bytes
              Scalar 28 bytes
        Total: 886 bytes in 15 elements

EXPORTS

Nothing per default, but can export the following per request:

        report_size
        track_size
        track_sizes
        hide_tracks
        element_type
        entries_per_element

        S_SCALAR
        S_HASH
        S_ARRAY
        S_GLOB
        S_UNKNOWN
        S_CODE
        S_LVALUE
        S_REGEXP
        S_CYCLE
        S_DOUBLE

        SF_KEY
        SF_REF
        SF_REF
        SF_WEAK
        SF_RO
        SF_VSTRING
        SF_DUAL

DESCRIPTION

Devel::Size can only report the size of a single element or the total size of a structure (array, hash etc). This module enhances Devel::Size by giving you the ability to generate a full size report for each element in a structure.

You have full control over how the generated text report looks like, and where you want to output it. In addition, the method track_size allows you to get at the raw data that is used to generate the report for even more flexibility.

METHODS

report_size

        my $record = report_size( $reference, $options ) . "\n";
        print $record;

Walks the given reference recursively and returns text tree describing the size of each element. $options is a hash, containing the following optional keys:

        names     ref to HASH mapping the types to names
                  This should map S_Scalar to something like "Scalar" etc
        indent    string to indent different levels with, default is '  '
        left      indent all text with this at the left side, default is ''
        inner     indent inner text with this at the left side, default is '  '
        total     if true, a total size will be printed as last line
        bytes     name of the size unit, defaults to 'bytes'
        head      header string, default 'Size report for'
                  Set to '' to supress header completely        
        overhead  Format string for the overhead, first size in bytes, then
                  the bytes string (see above) and then the percentage.
                  The default is:
                  " (overhead: %i%s, %0.2f%%)"
        addr      if true, for each element the memory address will be output
        class     if true, show the class each element was blessed in
        terse     if true, details for elements will be supressed, e.g. you
                  will only get the header, total and summary (if requested)
        summary   if true, print a table summing up the memory details on a
                  per-class basis
        doubles   If true, hash keys and array elemts that point to the same
                  thing in memory will be reported. Default is off, since it
                  saves memory. Note that you will usually only get double
                  entries in hashes and array by using Array::RefElem's methods
                  or similiar hacks/tricks.

entries_per_element

        my $entries = entries_per_element();

Returns the number of entries per element that track_size() will generate.

track_sizes

        $elements = track_sizes( $reference, $level);

Walk the given scalar or reference recursively and returns a ref to an array, containing entries_per_element entries for each element in the structure pointed to by $reference. $reference can also be a plain scalar.

The entries for each element are currently:

        level     the indent level
        type      the type of the element, S_SCALAR, S_HASH, S_ARRAY etc
                  if (type & SF_KEY) != 0, the element is a member of a hash
        size      size in bytes of the element
        overhead  if the element is an ARRAY or HASH, contains the overhead
                  in bytes (size - sum(size of all elements)).
        name      if type & SF_KEY != 0, this contains the name of the hash key
        addr      memory address of the element
        class     classname that the element was blessed into, or ''

track_size

        @elements = track_size( $reference, $level);

Works just like track_sizes, but for backward compatibility reasons returns an array with the results.

hide_tracks

        hide_tracks();

Releases the memory consumed by a call to track_size or track_sizes.

type

        $type_number = type($type_name);

Maps a type name (like 'SCALAR') to a type number (lilke S_SCALAR).

element_type

        $type_name = element_type($type_nr);

Maps a type number (like S_SCALAR) to a type name (lilke 'SCALAR').

WRAP YOUR OWN

If you want to create your own report with different formattings, please use track_size and create a report out of the data you get back from it. Look at the source code for report_size how to do this - it is easy!

CAVEATS

  • The limitations of Devel::Size also apply to this module. This means that CODE refs and other "obscure" things might show wrong sizes, or unknown overhead. In addition, some sizes might be reported wrong.

  • A string representation of the passed argument will be inserted when generating a report with a header.

    If the passed argument is an object with overloaded magic, then the routine for stringification will be triggered. If this routine does actually modify the object (for instance, Math::String objects cache their string form upon first call to stringification, thus modifying themselves), the reported size will be different from a first report without a header.

BUGS

threads

The results are currently stored in a global package var, so this is probably not threadsafe.

AUTHOR

(c) 2004, 2005, 2006, 2008 by Tels http://bloodgate.com