]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/csv: optimize Write by giving fieldNeedsQuotes a fast path for when Comma...
authorAlex Gaynor <alex@alloy.us>
Tue, 28 Apr 2020 01:18:29 +0000 (01:18 +0000)
committerIan Lance Taylor <iant@golang.org>
Tue, 5 May 2020 23:57:19 +0000 (23:57 +0000)
name     old time/op  new time/op  delta
Write-4  2.37µs ±20%  1.90µs ±19%  -19.54%  (p=0.015 n=6+6)

Change-Id: Iadfd9a43c958704c49ceb540b44d145220f9a72f
GitHub-Last-Rev: e7d8b0bd69870a24fdd800401d721e4c5bda7750
GitHub-Pull-Request: golang/go#34507
Reviewed-on: https://go-review.googlesource.com/c/go/+/197078
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/encoding/csv/writer.go
src/encoding/csv/writer_test.go

index 3f34bc51dbfc0ddb705771b75436a17203175337..ac64b4d54c8401c7903890a49a9257912aff95f8 100644 (file)
@@ -158,10 +158,24 @@ func (w *Writer) fieldNeedsQuotes(field string) bool {
        if field == "" {
                return false
        }
-       if field == `\.` || strings.ContainsRune(field, w.Comma) || strings.ContainsAny(field, "\"\r\n") {
+
+       if field == `\.` {
                return true
        }
 
+       if w.Comma < utf8.RuneSelf {
+               for i := 0; i < len(field); i++ {
+                       c := field[i]
+                       if c == '\n' || c == '\r' || c == '"' || c == byte(w.Comma) {
+                               return true
+                       }
+               }
+       } else {
+               if strings.ContainsRune(field, w.Comma) || strings.ContainsAny(field, "\"\r\n") {
+                       return true
+               }
+       }
+
        r1, _ := utf8.DecodeRuneInString(field)
        return unicode.IsSpace(r1)
 }
index 011f01c172ac10ea6a162a67fc70c0e4b5db635f..ab28b0d7c35bef81eca3890cb19e793af9388629 100644 (file)
@@ -93,3 +93,20 @@ func TestError(t *testing.T) {
                t.Error("Error should not be nil")
        }
 }
+
+var benchmarkWriteData = [][]string{
+       {"abc", "def", "12356", "1234567890987654311234432141542132"},
+       {"abc", "def", "12356", "1234567890987654311234432141542132"},
+       {"abc", "def", "12356", "1234567890987654311234432141542132"},
+}
+
+func BenchmarkWrite(b *testing.B) {
+       for i := 0; i < b.N; i++ {
+               w := NewWriter(&bytes.Buffer{})
+               err := w.WriteAll(benchmarkWriteData)
+               if err != nil {
+                       b.Fatal(err)
+               }
+               w.Flush()
+       }
+}