github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/tools/sizediff (about)

     1  #!/usr/bin/env python3
     2  
     3  # Small tool to compare code size between TinyGo runs (with the -size=short flag).
     4  
     5  import sys
     6  
     7  class Comparison:
     8      def __init__(self, command, flash0, ram0, flash1, ram1):
     9          self.command = command
    10          self.flash0 = flash0
    11          self.ram0 = ram0
    12          self.flash1 = flash1
    13          self.ram1 = ram1
    14  
    15      @property
    16      def ramdiff(self):
    17          return self.ram1 - self.ram0
    18  
    19      @property
    20      def flashdiff(self):
    21          return self.flash1 - self.flash0
    22  
    23  def readSizes(path):
    24      sizes = []
    25      lines = open(path).readlines()
    26      for i in range(len(lines)):
    27          if not lines[i].strip().startswith('code '):
    28              continue
    29          # found a size header
    30          code, data, bss, flash, ram = map(int, lines[i+1].replace("|", "").split())
    31          command = lines[i-1].strip()
    32          sizes.append({
    33              'command': command,
    34              'flash':   flash,
    35              'ram':     ram
    36          })
    37      return sizes
    38  
    39  def main():
    40      path0 = sys.argv[1]
    41      path1 = sys.argv[2]
    42      sizes0 = readSizes(path0)
    43      sizes1 = readSizes(path1)
    44      comparisons = []
    45      for i in range(len(sizes0)):
    46          if i >= len(sizes1):
    47              print('%s has more commands than %s' % (path0, path1))
    48              print('   ', sizes0[i]['command'])
    49              break
    50          if sizes0[i]['command'] != sizes1[i]['command']:
    51              print('not the same command!')
    52              print('   ', sizes0[i]['command'])
    53              print('   ', sizes1[i]['command'])
    54          comparisons.append(Comparison(sizes0[i]['command'], sizes0[i]['flash'], sizes0[i]['ram'], sizes1[i]['flash'], sizes1[i]['ram']))
    55      if len(sizes0) < len(sizes1):
    56          print('%s has more commands than %s' % (path1, path0))
    57          print('   ', sizes1[len(sizes0)]['command'])
    58      comparisons.sort(key=lambda x: x.flashdiff)
    59      totalFlash0 = 0
    60      totalFlash1 = 0
    61      totalRam0 = 0
    62      totalRam1 = 0
    63      totalDiff = 0
    64      totalRamDiff = 0
    65      totalProduct = 1
    66      totalRamProduct = 1
    67      print(' flash                          ram')
    68      print(' before   after   diff          before   after   diff')
    69      for comparison in comparisons:
    70          diffPct = comparison.flashdiff / comparison.flash0
    71          diffRamPct = comparison.ramdiff / comparison.ram0
    72          print('%7d %7d %6d %6.2f%% %7d %7d %6d %6.2f%% %s' % (comparison.flash0, comparison.flash1, comparison.flashdiff, diffPct * 100, comparison.ram0, comparison.ram1, comparison.ramdiff, diffRamPct * 100, comparison.command))
    73          totalFlash0 += comparison.flash0
    74          totalFlash1 += comparison.flash1
    75          totalDiff += comparison.flashdiff
    76          totalProduct *= (1 + diffPct)
    77          totalRam0 += comparison.ram0
    78          totalRam1 += comparison.ram1
    79          totalRamDiff += comparison.ramdiff
    80          totalRamProduct *= (1 + diffRamPct)
    81      geomean = totalProduct ** (1.0 / float(len(comparisons)))
    82      geomeanRam = totalRamProduct ** (1.0 / float(len(comparisons)))
    83      print('%7d %7d %6d %6.2f%% %7d %7d %6d %6.2f%%' % (totalFlash0, totalFlash1, totalDiff, geomean - 1, totalRam0, totalRam1, totalRamDiff, geomeanRam - 1))
    84  
    85  
    86  if __name__ == '__main__':
    87      main()