RetroArch icon indicating copy to clipboard operation
RetroArch copied to clipboard

Ideas on how to reduce size of settings_t struct

Open LibretroAdmin opened this issue 3 years ago • 2 comments

settings_t as defined in configuration.h is massive right now in terms of size.

Settings are divided into types - bools, ints, unsigned integers, char array variables, and floats. Bools are 8 bits in size, ints 32-bit signed, unsigned integers 32bit unsigned, and char arrays are of variable fixed-width sizes.

All of these variables are starting to add up:

  • signed integers (32bit) - 15 entries = 15 * 32 bits = 480 bits
  • unsigned integers (32bit) - 158 entries = 158 * 32 bits = 5056 bits
  • bools (8bit) - 339 entries = 339 * 8 bits = 2712 bits
  • floats (32bit) - 47 entries = 47 * 32 bits = 1504 bits
  • char arrays - not counted, of varying sizes.

Even though settings is allocated on the heap, size reductions could help. Some ideas on how we can reduce the size of this struct:

  • We do not need 32 bits for every unsigned/signed variable in this config struct. Depending on the max value that can be inputted for a given setting, 8bits or 16bits might just be enough. One of the solutions could be splitting up unsigneds into 8bit, 16bit and 32bit. For example, if a setting's max value can only reach 256, then we can downgrade the unsigned variable to an 8bit unsigned variable.
  • Instead of using a separate bool variable per setting, we could use unsigned 32bit variables instead and then use bitmasks. We would have to group these logically and intelligently since each 32bit unsigned variable would only be able to hold 32 flags. With 11 unsigned 32bit values, we could cover 352 boolean settings. 11 * 32 = 352 bits. This would be a big reduction from the current 2712 bits that the boolean settings currently occupy.
  • Look into the char arrays and ways we could reduce their sizes. Perhaps we can work more with base paths instead of full paths and assemble the full path on the fly at runtime before it is actually needed, that way we wouldn't have to store it in a huge MAX_PATH_LENGTH variable.

LibretroAdmin avatar Jun 10 '22 12:06 LibretroAdmin

Why not just use bitfields?

ghost avatar Jun 10 '22 16:06 ghost

The char arrays are so large that anything else isn't worth changing yet.

There are about 100 char arrays, 58 are PATH_MAX_LENGTH and could be replaced with char *, would save memory for any path that is a few char shorter than it's current max size (PATH_MAX_LENGTH is 512 or 4096 depending on platform, usually the latter), this could easily save 20,000-200,000 bytes (160,000-1,600,000 bits for comparison to the bits listed above).

Would lose use of sizeof() but can always set size as PATH_MAX_LENGTH in strlcpy(), etc. The existing char * that reference them can either just be a copy of the pointer or could be changed to char ** if really needed to track changes.

ZachCook avatar Aug 11 '22 17:08 ZachCook