Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binary size report in HTML #4661

Merged
merged 2 commits into from
Dec 19, 2024
Merged

Binary size report in HTML #4661

merged 2 commits into from
Dec 19, 2024

Conversation

aykevl
Copy link
Member

@aykevl aykevl commented Dec 17, 2024

This adds a -size-report flag that writes a HTML file with more detailed information on the binary size. This is similar to -size=full but also adds file level size usage.
Here is an example, with "C compiler-rt" expanded:
Screenshot_20241217_114048

Here you can see that 28 bytes go to memset, 92 bytes go to the count-leading-zeroes builtin (clzsi3), and the remaining bytes (92+14 = 106) go to an unsigned 32-bit divide builtin. This makes sense: the chip I used for testing is the nrf51 (in the microbit) which doesn't support clz or division so these need to be done in software.

If you expand the runtime package, you can also see that around 1kB of binary size is taken up by the GC, the rest is for various other runtime features like initialization and the scheduler.

I intend to add more to this size report in the future. Most importantly, a way to answer the question "why does my binary take up so much space, I didn't import that many packages!". Basically, a way to trace from the main package where all the binary size goes and how much a given package is responsible for the binary size of the program. While this could in theory all be done on the command line, doing this in HTML/CSS/JS makes the UX a whole lot better and more intuitive.

Copy link

github-actions bot commented Dec 17, 2024

Size difference with the dev branch:

Binary size difference
 flash                          ram
 before   after   diff          before   after   diff
  16720   16720      0   0.00%    4172    4172      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/adafruit4650
  61472   61472      0   0.00%    6180    6180      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/adt7410/main.go
   9568    9568      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/adxl345/main.go
  13568   13568      0   0.00%    6788    6788      0   0.00% tinygo build -size short -o ./build/test.hex -target=pybadge ./examples/amg88xx
   8680    8680      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/main.go
  11884   11884      0   0.00%    6580    6580      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/apds9960/proximity/main.go
   9760    9760      0   0.00%    4752    4752      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/itsybitsy-m0/main.go
   8368    8368      0   0.00%    2320    2320      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/at24cx/main.go
   8124    8124      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bh1750/main.go
   7432    7432      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/blinkm/main.go
  70632   70632      0   0.00%    3660    3660      0   0.00% tinygo build -size short -o ./build/test.hex -target=pinetime     ./examples/bma42x/main.go
  64012   64012      0   0.00%    6196    6196      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmi160/main.go
  27412   27412      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmp180/main.go
  64072   64072      0   0.00%    6228    6228      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmp280/main.go
  12200   12200      0   0.00%    4812    4812      0   0.00% tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/bmp388/main.go
   8176    8176      0   0.00%    3344    3344      0   0.00% tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/sram/main.go
  22216   22216      0   0.00%    3540    3540      0   0.00% tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/time/main.go
  69768   69768      0   0.00%    6368    6368      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/ds3231/main.go
   4620    4620      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/easystepper/main.go
  69304   69304      0   0.00%    6968    6968      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/flash/console/spi
  65644   65644      0   0.00%    9004    9004      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/flash/console/qspi
   7212    7212      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/gc9a01/main.go
  67628   67628      0   0.00%    6360    6360      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/gps/i2c/main.go
  68164   68164      0   0.00%    6504    6504      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/gps/uart/main.go
   7872    7872      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/hcsr04/main.go
   5832    5832      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hd44780/customchar/main.go
   5784    5784      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hd44780/text/main.go
  10528   10528      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/hd44780i2c/main.go
  14808   14808      0   0.00%    6580    6580      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/hts221/main.go
  16148   16148      0   0.00%    2360    2360      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hub75/main.go
  10152   10152      0   0.00%    6916    6916      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/basic
  10644   10644      0   0.00%    4868    4868      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/ili9341/basic
  29508   29508      0   0.00%   38076   38076      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/pyportal_boing
  10172   10172      0   0.00%    6916    6916      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/scroll
  10732   10732      0   0.00%    4868    4868      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/ili9341/scroll
 263712  263712      0   0.00%   46748   46748      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/slideshow
  11732   11732      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis3dh/main.go
  14152   14152      0   0.00%    6580    6580      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/lps22hb/main.go
  26132   26132      0   0.00%    2328    2328      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/lsm303agr/main.go
  12448   12448      0   0.00%    4788    4788      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/lsm6ds3/main.go
  10744   10744      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mag3110/main.go
   9920    9920      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp23017/main.go
  10372   10372      0   0.00%    4788    4788      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp23017-multiple/main.go
   9780    9780      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp3008/main.go
  68656   68656      0   0.00%    6188    6188      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp2515/main.go
  27224   27224      0   0.00%    3632    3632      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/microbitmatrix/main.go
  26944   26944      0   0.00%    5680    5680      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit-v2 ./examples/microbitmatrix/main.go
   8240    8240      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mma8653/main.go
   8148    8148      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mpu6050/main.go
  75640   75640      0   0.00%    7448    7448      0   0.00% tinygo build -size short -o ./build/test.hex -target=p1am-100 ./examples/p1am/main.go
  12264   12264      0   0.00%    3352    3352      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/pca9685/main.go
   6228    6228      0   0.00%    3288    3288      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setbuffer/main.go
   5260    5260      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setpixel/main.go
  10552   10552      0   0.00%    3328    3328      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/seesaw
   2825    2825      0   0.00%     558     558      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino ./examples/servo
  13792   13792      0   0.00%    3400    3400      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico     ./examples/sgp30
   8080    8080      0   0.00%    6788    6788      0   0.00% tinygo build -size short -o ./build/test.hex -target=pybadge ./examples/shifter/main.go
  57476   57476      0   0.00%    3684    3684      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht3x/main.go
  57532   57532      0   0.00%    3692    3692      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht4x/main.go
  57448   57448      0   0.00%    3684    3684      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/shtc3/main.go
   6688    6688      0   0.00%    2288    2288      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/i2c_128x32/main.go
   6140    6140      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/spi_128x64/main.go
   5844    5844      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1331/main.go
   6788    6788      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/st7735/main.go
   6700    6700      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/st7789/main.go
  16964   16964      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/thermistor/main.go
  10604   10604      0   0.00%    4540    4540      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-bluefruit ./examples/tone
  10064   10064      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/tm1637/main.go
  10880   10880      0   0.00%    3340    3340      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/touch/capacitive
   9524    9524      0   0.00%    6780    6780      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/touch/resistive/fourwire/main.go
  12596   12596      0   0.00%    6976    6976      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/touch/resistive/pyportal_touchpaint/main.go
  14980   14980      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/vl53l1x/main.go
  13460   13460      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/vl6180x/main.go
  24616   24616      0   0.00%   13720   13720      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-nrf52840-sense ./examples/waveshare-epd/epd1in54/main.go
   6488    6488      0   0.00%    2320    2320      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd2in13/main.go
   6176    6176      0   0.00%    2312    2312      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd2in13x/main.go
   6400    6400      0   0.00%    2320    2320      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd4in2/main.go
  26144   26144      0   0.00%   16412   16412      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/waveshare-epd/epd2in66b/main.go
   6848    6848      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/ws2812
   5764    5764      0   0.00%    9522    9522      0   0.00% tinygo build -size short -o ./build/test.bin -target=m5stamp-c3          ./examples/ws2812
  62532   62532      0   0.00%    5952    5952      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-nrf52840 ./examples/is31fl3731/main.go
   1581    1581      0   0.00%     598     598      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino   ./examples/ws2812
   1056    1056      0   0.00%     180     180      0   0.00% tinygo build -size short -o ./build/test.hex -target=digispark ./examples/ws2812
  31856   31856      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/bme280/main.go
2034810 2034810      0   0.00%  472394  472394      0   0.00%

@deadprogram
Copy link
Member

Any particular reason you did not just add another option to -size=report?

@aykevl
Copy link
Member Author

aykevl commented Dec 17, 2024

What would you propose as a command line flag?
Note that we'd need to specify the file name somehow, or pick a default one to store in /tmp.

@deadprogram
Copy link
Member

I misunderstood that the usage was -size-report=<filename> . Let me consider it...

@deadprogram
Copy link
Member

deadprogram commented Dec 17, 2024

How about adding a new flag size-report-file with a default value of size-report.html.

In addition, add the report option to the -size flag.

That way people can use -size=report and it basically does the same thing as other -size flag options, but CI can override the output location for the report if they need to for some reason.

@dgryski
Copy link
Member

dgryski commented Dec 17, 2024

Just to bikeshed a bit here, I think most Go tooling would use -size=html here and either write to a "known" output file or stdout.

@deadprogram
Copy link
Member

I like @dgryski suggestion.

@aykevl
Copy link
Member Author

aykevl commented Dec 19, 2024

Updated the PR with -size=html.
It will now also print the filename when writing the file.

@deadprogram
Copy link
Member

@aykevl please note CI failure.

This is not a big change over the existing size report with -size=full,
but it is a bit more readable.

More information will be added in subsequent commits.
Show which files cause a binary size increase. This makes it easier to
see where the size is going: for example, this makes it easy to see how
much the GC contributes to code size compared to other runtime parts.
@aykevl
Copy link
Member Author

aykevl commented Dec 19, 2024

Oops, yes, fixed.

@deadprogram deadprogram added this to the 0.35.0 milestone Dec 19, 2024
@deadprogram
Copy link
Member

Thanks for the changes to this feature @aykevl it works really well! Now merging.

@deadprogram deadprogram merged commit 9d2f528 into dev Dec 19, 2024
23 checks passed
@deadprogram deadprogram deleted the size-report branch December 19, 2024 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants