Skip to content

proposal: bmp280: remove allocation on read sensor data #760

Open
@muktihari

Description

@muktihari

When we read temperature or pressure, it will call this following line:
https://github.com/tinygo-org/drivers/blob/156d6e7c9ce473be185e1554c9da3c2983e6e26a/bmp280/bmp280.go#L220C1-L223C18

Which creates a slice with a dynamic n capacity. Since it's a dynamic slice, it's typically heap-allocated. The following program will prove that the allocation is indeed happening:

package main

import (
	"machine"
	"runtime"
	"time"

	"tinygo.org/x/drivers/bmp280"
)

func main() {
	machine.I2C1.Configure(machine.I2CConfig{
		Frequency: 400 * machine.KHz,
		SDA:       machine.GP6,
		SCL:       machine.GP7,
	})

	sensor := bmp280.New(machine.I2C1)
	sensor.Address = 0x76
	sensor.Configure(bmp280.STANDBY_125MS, bmp280.FILTER_4X, bmp280.SAMPLING_16X, bmp280.SAMPLING_16X, bmp280.MODE_FORCED)

	go func() {
		var init, memstats runtime.MemStats
		runtime.ReadMemStats(&init)
		for {
			runtime.ReadMemStats(&memstats)
			println("#", init.HeapAlloc, memstats.HeapAlloc, memstats.HeapAlloc-init.HeapAlloc)
			time.Sleep(1 * time.Second)
		}
	}()

	for {
		temp, _  := sensor.ReadTemperature()
		println("temp:", temp)
		time.Sleep(time.Second)
	}
}

Output:

➜ tinygo monitor
Connected to /dev/ttyACM0. Press Ctrl-C to exit.
# 16448 16496 48
temp: 31560
# 16448 16512 64
temp: 31560
# 16448 16528 80
temp: 31560
# 16448 16544 96
temp: 31570
# 16448 16560 112
temp: 31570
# 16448 16576 128
temp: 31570

I believe that reading from a sensor is considered a hotpath as users may frequently read data from it. So I propose fixing this by creating fixed slice from the caller (ReadTemperature and ReadPressure) and then pass the slice to readData method, instead of passing the capacity into it, e.g.:

func (d *Device) ReadPressure() (pressure int32, err error) 
- data, err := d.readData(REG_PRES, 6)
- if err != nil {
+ data := make([]byte, 6)
+ if err = d.readData(REG_PRES, data); err != nil {
	return
}

In my testing, this changes remove the allocation:

➜ tinygo monitor
Connected to /dev/ttyACM0. Press Ctrl-C to exit.
# 16448 16448 0
temp: 31880
# 16448 16448 0
temp: 31890
# 16448 16448 0
temp: 31890
# 16448 16448 0
temp: 31900
# 16448 16448 0
temp: 31900
# 16448 16448 0
temp: 31900

I can submit a PR if this approach is accepted. Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions