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

Optimize frame encodeValue unencodeValue, replace with more efficient version #58

Merged
merged 1 commit into from Feb 12, 2019

Conversation

@hanjm
Copy link

@hanjm hanjm commented Feb 7, 2019

Using strings.Replace multi times in "encodeValue" and "unencodeValue" function is low efficience, strings.NewReplacer is the more efficient version, here is the benchmark result.

/*
$ go test -check.v -check.b -check.bmem
PASS: encode_test.go:32: EncodeSuite.BenchmarkEncodeValue       10000000               223 ns/op             112 B/op          1 allocs/op
PASS: encode_test.go:48: EncodeSuite.BenchmarkEncodeValueOld     5000000               504 ns/op             480 B/op          9 allocs/op
PASS: encode_test.go:40: EncodeSuite.BenchmarkUnencodeValue      5000000               357 ns/op             208 B/op          4 allocs/op
PASS: encode_test.go:56: EncodeSuite.BenchmarkUnencodeValueOld   5000000               556 ns/op             448 B/op          9 allocs/op
OK: 4 passed
PASS
*/
func (s *EncodeSuite) BenchmarkEncodeValue(c *C) {
	val := "Contains\r\nNewLine and : colon and \\ backslash"
	c.ResetTimer()
	for i := 0; i < c.N; i++ {
		encodeValue(val)
	}
}

func (s *EncodeSuite) BenchmarkUnencodeValue(c *C) {
	val := []byte(`Contains\r\nNewLine and \c colon and \\ backslash`)
	c.ResetTimer()
	for i := 0; i < c.N; i++ {
		unencodeValue(val)
	}
}

func (s *EncodeSuite) BenchmarkEncodeValueOld(c *C) {
	val := "Contains\r\nNewLine and : colon and \\ backslash"
	c.ResetTimer()
	for i := 0; i < c.N; i++ {
		encodeValueOld(val)
	}
}

func (s *EncodeSuite) BenchmarkUnencodeValueOld(c *C) {
	val := []byte(`Contains\r\nNewLine and \c colon and \\ backslash`)
	c.ResetTimer()
	for i := 0; i < c.N; i++ {
		unencodeValueOld(val)
	}
}

func encodeValueOld(s string) []byte {
	s = strings.Replace(s, "\\", "\\\\", -1)
	s = strings.Replace(s, "\r", "\\r", -1)
	s = strings.Replace(s, "\n", "\\n", -1)
	s = strings.Replace(s, ":", "\\c", -1)
	return []byte(s)
}

func unencodeValueOld(b []byte) (string, error) {
	s := string(b)
	s = strings.Replace(s, "\\r", "\r", -1)
	s = strings.Replace(s, "\\n", "\n", -1)
	s = strings.Replace(s, "\\c", ":", -1)
	s = strings.Replace(s, "\\\\", "\\", -1)
	return s, nil
}
frame/encode.go Show resolved Hide resolved
frame/encode.go Show resolved Hide resolved
frame/encode.go Show resolved Hide resolved
frame/encode.go Show resolved Hide resolved
frame/encode_test.go Outdated Show resolved Hide resolved
@hanjm hanjm force-pushed the hanjm:master branch from c38c63d to a964184 Feb 8, 2019
@hanjm
Copy link
Author

@hanjm hanjm commented Feb 10, 2019

you can see the std lib code, strings/replace.go https://golang.org/src/strings/replace.go#L315:

func (r *genericReplacer) Replace(s string) string {
	buf := make(appendSliceWriter, 0, len(s))
	r.WriteString(&buf, s)
	return string(buf)
}

using []byte(replacerForEncodeValue.Replace(s)) make unnecessary bytes to string and strings to bytes transformation.

@worg
worg approved these changes Feb 12, 2019
@worg worg merged commit 51f02fb into go-stomp:master Feb 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

2 participants