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

Avoid dynamic memory allocation where practical #12

Open
anzdaddy opened this issue Jan 3, 2019 · 0 comments
Open

Avoid dynamic memory allocation where practical #12

anzdaddy opened this issue Jan 3, 2019 · 0 comments

Comments

@anzdaddy
Copy link
Member

anzdaddy commented Jan 3, 2019

For example, (Decimal64).Format allocates a buffer to pass to (Decimal64).Append but ends up passing it to (fmt.State).Write, which might be simply copying the buffer into another already allocated buffer.

The solution might be to reverse the roles. Format implements the algorithm and Append calls it like so:

type appender struct {
	buf []byte
	prec int
}

func (a *appender) Write(b []byte) (n int, err error) {
	a.buf = append(a.buf, b...)
	return n, nil
}

func (a *appender) Width() (wid int, ok bool) {
	return 0, false
}

func (a *appender) Precision() (prec int, ok bool) {
	return a.prec, true
}

func (a *appender) Flag(c int) bool {
	return false
}

// Append appends the text representation of d to buf.
func (d Decimal64) Append(buf []byte, format byte, prec int) []byte {
	a := appender{buf, prec}
	d.Format(&a, rune(format))
	return a.buf
}

// Format implements fmt.Formatter.
func (d Decimal64) Format(s fmt.State, format rune) {
	// Declare big enough local array to avoid dynamic allocation.
	var data [25]byte

	// Use the same algo as Append currently does
	buf := data[:]
	prec, havePrec := s.Precision()
	⋮
	if _, err := s.Write(buf); err != nil {
		panic(err)
	}
}

To reiterate, the above is just one case. There might be others. Also, it's possible the above solution yields worse performance, so don't assume, profile.

@anzdaddy anzdaddy added enhancement New feature or request ⚡ performance and removed enhancement New feature or request labels Jan 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant