-
Notifications
You must be signed in to change notification settings - Fork 909
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
runtime: optimize findHead #4574
Draft
aykevl
wants to merge
1
commit into
dev
Choose a base branch
from
gc-findHead-2
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Size difference with the dev branch: Binary size differenceflash ram before after diff before after diff 2825 2825 0 0.00% 558 558 0 0.00% tinygo build -size short -o ./build/test.hex -target=arduino ./examples/servo 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 63868 63884 16 0.03% 6196 6196 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmi160/main.go 69600 69616 16 0.02% 6376 6376 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/ds3231/main.go 69144 69160 16 0.02% 6976 6976 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/flash/console/spi 65532 65548 16 0.02% 9012 9012 0 0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/flash/console/qspi 67540 67556 16 0.02% 6368 6368 0 0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/gps/i2c/main.go 68076 68092 16 0.02% 6504 6504 0 0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/gps/uart/main.go 263524 263540 16 0.01% 46760 46760 0 0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/slideshow 26092 26108 16 0.06% 2328 2328 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/lsm303agr/main.go 57364 57380 16 0.03% 3700 3700 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht4x/main.go 57272 57288 16 0.03% 3692 3692 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/shtc3/main.go 62324 62340 16 0.03% 5952 5952 0 0.00% tinygo build -size short -o ./build/test.hex -target=feather-nrf52840 ./examples/is31fl3731/main.go 31816 31832 16 0.05% 4788 4788 0 0.00% tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/bme280/main.go 71208 71224 16 0.02% 6344 6344 0 0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/alarm/ 31336 31352 16 0.05% 4548 4548 0 0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/ssd1289/main.go 62196 62212 16 0.03% 3788 3788 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ndir/main_ndir.go 296580 296596 16 0.01% 13788 13788 0 0.00% tinygo build -size short -o ./build/test.hex -target=pyportal -stack-size 8kb ./examples/net/http-get/ 119288 119304 16 0.01% 7848 7848 0 0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 -stack-size 8kb ./examples/net/tcpclient/ 286056 286072 16 0.01% 17812 17812 0 0.00% tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/webserver/ 287076 287092 16 0.01% 18212 18212 0 0.00% tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/mqttclient/paho/ 16840 16860 20 0.12% 4324 4324 0 0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/adafruit4650 9528 9548 20 0.21% 4756 4756 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/adxl345/main.go 13528 13548 20 0.15% 6796 6796 0 0.00% tinygo build -size short -o ./build/test.hex -target=pybadge ./examples/amg88xx 8640 8660 20 0.23% 4748 4748 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/main.go 11768 11788 20 0.17% 6580 6580 0 0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/apds9960/proximity/main.go 9756 9776 20 0.21% 4768 4768 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/itsybitsy-m0/main.go 8332 8352 20 0.24% 2320 2320 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/at24cx/main.go 8084 8104 20 0.25% 4748 4748 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bh1750/main.go 7392 7412 20 0.27% 4748 4748 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/blinkm/main.go 12172 12192 20 0.16% 4820 4820 0 0.00% tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/bmp388/main.go 8164 8184 20 0.24% 3348 3348 0 0.00% tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/sram/main.go 22152 22172 20 0.09% 3544 3544 0 0.00% tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/time/main.go 4580 4600 20 0.44% 2280 2280 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/easystepper/main.go 7172 7192 20 0.28% 2280 2280 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/gc9a01/main.go 7832 7852 20 0.26% 4748 4748 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/hcsr04/main.go 5792 5812 20 0.35% 2280 2280 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hd44780/customchar/main.go 5744 5764 20 0.35% 2280 2280 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hd44780/text/main.go 10488 10508 20 0.19% 4756 4756 0 0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/hd44780i2c/main.go 14692 14712 20 0.14% 6580 6580 0 0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/hts221/main.go 16108 16128 20 0.12% 2360 2360 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hub75/main.go 10116 10136 20 0.20% 6916 6916 0 0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/basic 10604 10624 20 0.19% 4868 4868 0 0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/ili9341/basic 29488 29508 20 0.07% 38076 38076 0 0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/pyportal_boing 10136 10156 20 0.20% 6924 6924 0 0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/scroll 10692 10712 20 0.19% 4876 4876 0 0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/ili9341/scroll 11692 11712 20 0.17% 4788 4788 0 0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis3dh/main.go 14036 14056 20 0.14% 6580 6580 0 0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/lps22hb/main.go 12408 12428 20 0.16% 4796 4796 0 0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/lsm6ds3/main.go 10704 10724 20 0.19% 4748 4748 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mag3110/main.go 9892 9912 20 0.20% 4780 4780 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp23017/main.go 10328 10348 20 0.19% 4788 4788 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp23017-multiple/main.go 9740 9760 20 0.21% 4748 4748 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp3008/main.go 8200 8220 20 0.24% 4756 4756 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mma8653/main.go 8108 8128 20 0.25% 4748 4748 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mpu6050/main.go 12232 12252 20 0.16% 3352 3352 0 0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/pca9685/main.go 6188 6208 20 0.32% 3288 3288 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setbuffer/main.go 5220 5240 20 0.38% 2280 2280 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setpixel/main.go 10516 10536 20 0.19% 3328 3328 0 0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/seesaw 13748 13768 20 0.15% 3400 3400 0 0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/sgp30 8044 8064 20 0.25% 6796 6796 0 0.00% tinygo build -size short -o ./build/test.hex -target=pybadge ./examples/shifter/main.go 6648 6668 20 0.30% 2288 2288 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/i2c_128x32/main.go 6100 6120 20 0.33% 2280 2280 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/spi_128x64/main.go 5808 5828 20 0.34% 2280 2280 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1331/main.go 6748 6768 20 0.30% 2280 2280 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/st7735/main.go 6660 6680 20 0.30% 2280 2280 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/st7789/main.go 10496 10516 20 0.19% 4540 4540 0 0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-bluefruit ./examples/tone 10028 10048 20 0.20% 4748 4748 0 0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/tm1637/main.go 10848 10868 20 0.18% 3340 3340 0 0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/touch/capacitive 9504 9524 20 0.21% 6788 6788 0 0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/touch/resistive/fourwire/main.go 12572 12592 20 0.16% 6984 6984 0 0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/touch/resistive/pyportal_touchpaint/main.go 14956 14976 20 0.13% 4756 4756 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/vl53l1x/main.go 13432 13452 20 0.15% 4756 4756 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/vl6180x/main.go 24676 24696 20 0.08% 13892 13892 0 0.00% tinygo build -size short -o ./build/test.hex -target=feather-nrf52840-sense ./examples/waveshare-epd/epd1in54/main.go 6452 6472 20 0.31% 2320 2320 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd2in13/main.go 6140 6160 20 0.33% 2312 2312 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd2in13x/main.go 6364 6384 20 0.31% 2320 2320 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd4in2/main.go 26420 26440 20 0.08% 16732 16732 0 0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/waveshare-epd/epd2in66b/main.go 6808 6828 20 0.29% 4788 4788 0 0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/ws2812 5734 5754 20 0.35% 9538 9538 0 0.00% tinygo build -size short -o ./build/test.bin -target=m5stamp-c3 ./examples/ws2812 11052 11072 20 0.18% 4748 4748 0 0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/buzzer/main.go 12760 12780 20 0.16% 4788 4788 0 0.00% tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/veml6070/main.go 6724 6744 20 0.30% 4748 4748 0 0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l293x/simple/main.go 8636 8656 20 0.23% 4748 4748 0 0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l293x/speed/main.go 6692 6712 20 0.30% 4748 4748 0 0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l9110x/simple/main.go 9244 9264 20 0.22% 4756 4756 0 0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l9110x/speed/main.go 7308 7328 20 0.27% 3320 3320 0 0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-f103rb ./examples/shiftregister/main.go 6976 6996 20 0.29% 2268 2268 0 0.00% tinygo build -size short -o ./build/test.hex -target=hifive1b ./examples/ssd1351/main.go 12964 12984 20 0.15% 4748 4748 0 0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis2mdl/main.go 8840 8860 20 0.23% 4764 4764 0 0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/max72xx/main.go 36512 36532 20 0.05% 3988 3988 0 0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/pcf8523/ 7236 7256 20 0.28% 4748 4748 0 0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/clkout/ 12168 12188 20 0.16% 3304 3304 0 0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/qmi8658c/main.go 10788 10808 20 0.19% 3288 3288 0 0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/pcf8591/ 8716 8736 20 0.23% 4756 4756 0 0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/ina260/main.go 13156 13176 20 0.15% 4788 4788 0 0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/ina219/main.go 9300 9320 20 0.22% 5260 5260 0 0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-l432kc ./examples/aht20/main.go 10260 10280 20 0.19% 6796 6796 0 0.00% tinygo build -size short -o ./build/test.elf -target=wioterminal ./examples/axp192/m5stack-core2-blinky/ 9008 9028 20 0.22% 3276 3276 0 0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/xpt2046/main.go 13720 13740 20 0.15% 4940 4940 0 0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-wl55jc ./examples/sx126x/lora_rxtx/ 11236 11256 20 0.18% 4252 4252 0 0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/irremote/main.go 11932 11952 20 0.17% 3324 3324 0 0.00% tinygo build -size short -o ./build/test.hex -target=badger2040 ./examples/uc8151/main.go 10408 10428 20 0.19% 3356 3356 0 0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/scd4x/main.go 8512 8532 20 0.23% 4748 4748 0 0.00% tinygo build -size short -o ./build/test.uf2 -target=circuitplay-express ./examples/makeybutton/main.go 9624 9644 20 0.21% 4772 4772 0 0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/ds18b20/main.go 15896 15916 20 0.13% 4880 4880 0 0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/as560x/main.go 9868 9888 20 0.20% 3296 3296 0 0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mpu6886/main.go 7768 7788 20 0.26% 4748 4748 0 0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/ttp229/main.go 9296 9316 20 0.22% 3288 3288 0 0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mpu9150/main.go 11376 11396 20 0.18% 3324 3324 0 0.00% tinygo build -size short -o ./build/test.hex -target=macropad-rp2040 ./examples/sh1106/macropad_spi 8436 8456 20 0.24% 3760 3760 0 0.00% tinygo build -size short -o ./build/test.hex -target=macropad-rp2040 ./examples/encoders/quadrature-interrupt 61312 61336 24 0.04% 6196 6196 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/adt7410/main.go 70472 70496 24 0.03% 3660 3660 0 0.00% tinygo build -size short -o ./build/test.hex -target=pinetime ./examples/bma42x/main.go 27380 27404 24 0.09% 4788 4788 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmp180/main.go 63912 63936 24 0.04% 6228 6228 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmp280/main.go 68488 68512 24 0.04% 6196 6196 0 0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp2515/main.go 27220 27244 24 0.09% 3648 3648 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/microbitmatrix/main.go 26948 26972 24 0.09% 5696 5696 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit-v2 ./examples/microbitmatrix/main.go 75768 75792 24 0.03% 7480 7480 0 0.00% tinygo build -size short -o ./build/test.hex -target=p1am-100 ./examples/p1am/main.go 57300 57324 24 0.04% 3692 3692 0 0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht3x/main.go 16924 16948 24 0.14% 4748 4748 0 0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/thermistor/main.go 16412 16436 24 0.15% 4732 4732 0 0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/microphone/main.go 77180 77204 24 0.03% 6344 6344 0 0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/dht/main.go 70736 70760 24 0.03% 6340 6340 0 0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/time/ 71168 71192 24 0.03% 6352 6352 0 0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/timer/ 72620 72644 24 0.03% 10748 10748 0 0.00% tinygo build -size short -o ./build/test.hex -target=feather-m4 ./examples/sdcard/console/ 61416 61440 24 0.04% 8232 8232 0 0.00% tinygo build -size short -o ./build/test.hex -target=feather-m4 ./examples/i2csoft/adt7410/ 83056 83080 24 0.03% 6588 6588 0 0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-wl55jc ./examples/lora/lorawan/atcmd/ 66752 66776 24 0.04% 4816 4816 0 0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/ndir/main_ndir.go 65172 65196 24 0.04% 6260 6260 0 0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/ndir/main_ndir.go 65712 65736 24 0.04% 4784 4784 0 0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mcp9808/main.go 85868 85892 24 0.03% 5140 5140 0 0.00% tinygo build -size short -o ./build/test.hex -target=challenger-rp2040 ./examples/net/ntpclient/ 245444 245468 24 0.01% 10488 10488 0 0.00% tinygo build -size short -o ./build/test.hex -target=nano-rp2040 -stack-size 8kb ./examples/net/websocket/dial/ 103048 103072 24 0.02% 9816 9816 0 0.00% tinygo build -size short -o ./build/test.hex -target=metro-m4-airlift -stack-size 8kb ./examples/net/socket/ 338356 338380 24 0.01% 15396 15396 0 0.00% tinygo build -size short -o ./build/test.hex -target=matrixportal-m4 -stack-size 8kb ./examples/net/webstatic/ 111492 111516 24 0.02% 7772 7772 0 0.00% tinygo build -size short -o ./build/test.hex -target=arduino-mkrwifi1010 -stack-size 8kb ./examples/net/tlsclient/ 154136 154160 24 0.02% 6540 6540 0 0.00% tinygo build -size short -o ./build/test.hex -target=nano-rp2040 -stack-size 8kb ./examples/net/mqttclient/natiu/ 116992 117016 24 0.02% 13132 13132 0 0.00% tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/webclient/ 5326300 5329052 2752 0.00% 811790 811790 0 0.00% |
This is similar to #3899, but smaller and hopefully just as efficient.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is similar to #3899, but smaller and hopefully just as efficient.
Needs a bit of cleanup before being ready.