diff --git a/sanitize.go b/sanitize.go index 911c734b..2a0f7ed9 100644 --- a/sanitize.go +++ b/sanitize.go @@ -22,6 +22,7 @@ package tally import ( "bytes" + "sync" ) var ( @@ -124,6 +125,21 @@ func (s sanitizer) Value(v string) string { return s.valueFn(v) } +var _sanitizeBuffers = sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, +} + +func getSanitizeBuffer() *bytes.Buffer { + return _sanitizeBuffers.Get().(*bytes.Buffer) +} + +func putSanitizeBuffer(b *bytes.Buffer) { + b.Reset() + _sanitizeBuffers.Put(b) +} + func (c *ValidCharacters) sanitizeFn(repChar rune) SanitizeFn { return func(value string) string { var buf *bytes.Buffer @@ -155,7 +171,7 @@ func (c *ValidCharacters) sanitizeFn(repChar rune) SanitizeFn { // ie the character is invalid, and the buffer has not been initialised // so we initialise buffer and backfill if buf == nil { - buf = bytes.NewBuffer(make([]byte, 0, len(value))) + buf = getSanitizeBuffer() if idx > 0 { buf.WriteString(value[:idx]) } @@ -171,6 +187,8 @@ func (c *ValidCharacters) sanitizeFn(repChar rune) SanitizeFn { } // otherwise, return the newly constructed buffer - return buf.String() + result := buf.String() + putSanitizeBuffer(buf) + return result } } diff --git a/sanitize_test.go b/sanitize_test.go index a75d3459..5b2318df 100644 --- a/sanitize_test.go +++ b/sanitize_test.go @@ -58,3 +58,11 @@ func TestSanitizeTestCases(t *testing.T) { require.Equal(t, tc.output, fn(tc.input)) } } + +func BenchmarkSanitizeFn(b *testing.B) { + sanitize := newTestSanitizer() + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = sanitize("foo bar") + } +}