From b65e32b7e1770d0bf8ab0491dc8712baa40b4b16 Mon Sep 17 00:00:00 2001 From: Robert Williamson Date: Sat, 9 May 2015 17:21:22 -0500 Subject: [PATCH] difflib: optimize SplitLines --- difflib/difflib.go | 6 ++---- difflib/difflib_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/difflib/difflib.go b/difflib/difflib.go index 60ad7ff..64cc40f 100644 --- a/difflib/difflib.go +++ b/difflib/difflib.go @@ -752,9 +752,7 @@ func GetContextDiffString(diff ContextDiff) (string, error) { // Split a string on "\n" while preserving them. The output can be used // as input for UnifiedDiff and ContextDiff structures. func SplitLines(s string) []string { - lines := []string{} - for _, line := range strings.Split(s, "\n") { - lines = append(lines, line+"\n") - } + lines := strings.SplitAfter(s, "\n") + lines[len(lines)-1] += "\n" return lines } diff --git a/difflib/difflib_test.go b/difflib/difflib_test.go index 3924e80..94670be 100644 --- a/difflib/difflib_test.go +++ b/difflib/difflib_test.go @@ -317,3 +317,36 @@ func TestOutputFormatNoTrailingTabOnEmptyFiledate(t *testing.T) { assertEqual(t, err, nil) assertEqual(t, SplitLines(cd)[:2], []string{"*** Original\n", "--- Current\n"}) } + +func TestSplitLines(t *testing.T) { + allTests := []struct { + input string + want []string + }{ + {"foo", []string{"foo\n"}}, + {"foo\nbar", []string{"foo\n", "bar\n"}}, + {"foo\nbar\n", []string{"foo\n", "bar\n", "\n"}}, + } + for _, test := range allTests { + assertEqual(t, SplitLines(test.input), test.want) + } +} + +func benchmarkSplitLines(b *testing.B, count int) { + str := strings.Repeat("foo\n", count) + + b.ResetTimer() + + n := 0 + for i := 0; i < b.N; i++ { + n += len(SplitLines(str)) + } +} + +func BenchmarkSplitLines100(b *testing.B) { + benchmarkSplitLines(b, 100) +} + +func BenchmarkSplitLines10000(b *testing.B) { + benchmarkSplitLines(b, 10000) +}