Tuesday, January 25, 2011

Executable size measurements

I've been working on improving my Python script that takes the output of 'nm' and parses it to get a sense of how much space in the executable is being taken up by various data structures output by the compiler. Here's what the output looks like:

Total size:  155824

Category                          Count   Size Average Percent
================================ ====== ====== ======= =======
Reflection                           --  39088      --    25.1
  Composite types                   128  22528     176    14.5
  Enum types                          1     64      64     0.0
  Other types                         9    576      64     0.4
  Type references                     2     80      40     0.1
  Type lists                         45   1616      35     1.0
  Invokers                            8   6240     780     4.0
  Name tables (head)                 42   2880      68     1.8
  Name tables (simple)               41   3591      87     2.3
  Name tables (compound)             29    793      27     0.5
  Field offsets                      39    720      18     0.5

TIB                                  --  12384      --     7.9
  TypeInfoBlocks                    128   7040      55     4.5
  Base class lists                   56   1856      33     1.2
  IDispatch functions                91   3488      38     2.2

Standard Library                     --  94492      --    60.6
  tart.core                         209  15944      76    10.2
  tart.collections                  214  40016     186    25.7
  tart.gc                            16   1012      63     0.6
  tart.io                             0      0       0     0.0
  tart.reflect                      165  30096     182    19.3
  tart.testing                       10   2896     289     1.9
  tart.text                          22   4528     205     2.9

Classes                              --  57976      --    37.2
  tart.core.Array                   177  13928      78     8.9
  tart.core.String                   21   5152     245     3.3
  tart.collections.ArrayList         86  22944     266    14.7
  tart.collections.ImmutableList     69  14672     212     9.4
  tart.collections.List              21   1280      60     0.8

Static strings                      151  10728      71     6.9
Trace tables                         39    736      18     0.5

You'll note that in some cases the percentages add up to more than 100%. That's because not all of the categories are exclusive - for example, a given symbol can be in both the "Reflection" and "Standard Library" subheadings.

Also note that the actual size of the binary file being analyzed was 332049 bytes, not 155824 as is claimed above. The 155824 number only includes symbols that were generated by the Tart compiler.

A few surprising things:
  • CompositeType structures, which serve the function of metaclasses, take up 14% of the space. I have an idea how to make that smaller, however.
  • Invoker functions, which are responsible for boxing and unboxing of parameters when calling a method via reflection, take up 4% of the space. I'm not sure these can be shrunk significantly.
  • ArrayList is much bigger than Array. Note that for templated classes such as Array and ArrayList, the size includes all template expansions for different type parameters.

No comments:

Post a Comment