Program size analysis

Hi all! I'm trying to find ways to decrease my (SPM) library footprint for consuming apps. Specifically I'm looking at code-level size (not resource/assets). Does anyone have any good suggestions?

Apple's App Thinning Size Report.txt is a nice high-level summary, but doesn't help in narrowing down what code is contributing most to the compiled output.

I've tried using nm, but the --print-size option seems useless on my target executable. (Binary extracted from .ipa file, generated by Xcode). The only entry that has an address or size is __mh_execute_header.

Looking at the intermediate .o files from Xcode, helps a little as I can see the relative sizes of different classes (though the total size is a good deal larger than the file uncompressed .ipa file). Attempting to use nm --print-size here also only reports 0 for sizes.

The size tool seems to give high level summaries.

objdump --macho -x is interesting, but doesn't seem to include sizes.

machodump seems to be a little confused.

Are there any other tools that can help with determining contributions to binary size for Swift programs/libraries (specifically iOS)?

Is it valid to simply look at the difference between offsets from nm -p or objdump --macho -t?

Thanks!

1 Like

Bloaty is a useful tool for this which works for Swift and iOS binaries (although it doesn't have any automatic demangling for Swift symbol names).

Thanks @tgoyne, I looked at bloaty as well, but it also seems to only give a file-level summary and does not break things down to the function level.

bloaty -d sections,symbols gives you section and symbol-level information.

My version of bloaty (1.1.10) does not have that option. :frowning: (-d seems to be for another purpose.)

Bloaty McBloatface: a size profiler for binaries.

USAGE: bloaty [OPTION]... FILE... [-- BASE_FILE...]

Options:

  --csv              Output in CSV format instead of human-readable.
  --tsv              Output in TSV format instead of human-readable.
  -c FILE            Load configuration from <file>.
  -d SOURCE,SOURCE   Comma-separated list of sources to scan.
  --debug-file=FILE  Use this file for debug symbols and/or symbol table.
  -C MODE            How to demangle symbols.  Possible values are:
  --demangle=MODE      --demangle=none   no demangling, print raw symbols
                       --demangle=short  demangle, but omit arg/return types
                       --demangle=full   print full demangled type
                     The default is --demangle=short.
  --disassemble=FUNCTION
                     Disassemble this function (EXPERIMENTAL)
  --domain=DOMAIN    Which domains to show.  Possible values are:
                       --domain=vm
                       --domain=file
                       --domain=both (the default)
  -n NUM             How many rows to show per level before collapsing
                     other keys into '[Other]'.  Set to '0' for unlimited.
                     Defaults to 20.
  -s SORTBY          Whether to sort by VM or File size.  Possible values
                     are:
                       -s vm
                       -s file
                       -s both (the default: sorts by max(vm, file)).
  -w                 Wide output; don't truncate long labels.
  --help             Display this message and exit.
  --list-sources     Show a list of available sources and exit.
  --source-filter=PATTERN
                     Only show keys with names matching this pattern.

Options for debugging Bloaty:

  --debug-vmaddr=ADDR
  --debug-fileoff=OFF
                     Print extended debugging information for the given
                     VM address and/or file offset.
  -v                 Verbose output.  Dumps warnings encountered during
                     processing and full VM/file maps at the end.
                     Add more v's (-vv, -vvv) for even more.