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

Benchmark encoder against strings.Join style implementation #20

Open
at15 opened this issue Aug 11, 2018 · 1 comment
Open

Benchmark encoder against strings.Join style implementation #20

at15 opened this issue Aug 11, 2018 · 1 comment

Comments

@at15
Copy link
Member

at15 commented Aug 11, 2018

When working on gommon errors, came back to hashicorp/go-multierrors and they use strings.Join https://github.com/hashicorp/go-multierror/blob/master/format.go#L26:20 and the implementation is a bit different style compared to how we write encoder

func Join(a []string, sep string) string {
	switch len(a) {
	case 0:
		return ""
	case 1:
		return a[0]
	case 2:
		// Special case for common small values.
		// Remove if golang.org/issue/6714 is fixed
		return a[0] + sep + a[1]
	case 3:
		// Special case for common small values.
		// Remove if golang.org/issue/6714 is fixed
		return a[0] + sep + a[1] + sep + a[2]
	}
	n := len(sep) * (len(a) - 1)
	for i := 0; i < len(a); i++ {
		n += len(a[i])
	}

	b := make([]byte, n)
	bp := copy(b, a[0])
	for _, s := range a[1:] {
		bp += copy(b[bp:], sep)
		bp += copy(b[bp:], s)
	}
	return string(b)
}

https://github.com/libtsdb/libtsdb-go/blob/master/libtsdb/common/influxdb/encoder.go

func (e *Encoder) WritePointIntTagged(p *pb.PointIntTagged) {
	e.Buf = append(e.Buf, p.Name...)
	e.Buf = append(e.Buf, ',')
	for _, tag := range p.Tags {
		e.Buf = append(e.Buf, tag.K...)
		e.Buf = append(e.Buf, '=')
		e.Buf = append(e.Buf, tag.V...)
		e.Buf = append(e.Buf, ',')
	}
	e.Buf[len(e.Buf)-1] = ' '
	e.Buf = append(e.Buf, e.DefaultField...)
	e.Buf = append(e.Buf, '=')
	e.Buf = strconv.AppendInt(e.Buf, p.Point.V, 10)
	e.Buf = append(e.Buf, ' ')
	e.Buf = strconv.AppendInt(e.Buf, p.Point.T, 10)
	e.Buf = append(e.Buf, '\n')
}

not sure which one is faster, my implementation is likely to have more allocation because the slice is large enough ... though in our case since clients are not thread safe and use just one large slice as buffer, it's pretty likely no allocation will happen ....

@at15
Copy link
Member Author

at15 commented Feb 4, 2020

It is a good use case for benchhub, so just keep it open for now ... I always spend so much time on micro optimizing ... meh.

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

No branches or pull requests

1 participant