From ecf3ae90ff4741c91292825f3a73042146c84e9b Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Wed, 29 Nov 2017 21:47:00 +0000 Subject: [PATCH 1/3] add a benchmark for report unmarshalling --- report/benchmark_internal_test.go | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 report/benchmark_internal_test.go diff --git a/report/benchmark_internal_test.go b/report/benchmark_internal_test.go new file mode 100644 index 0000000000..568372b50c --- /dev/null +++ b/report/benchmark_internal_test.go @@ -0,0 +1,40 @@ +package report + +import ( + "flag" + "os" + "path/filepath" + "testing" +) + +var ( + benchReportPath = flag.String("bench-report-path", "", "report file, or dir with files, to use for benchmarking (relative to this package)") +) + +func BenchmarkReportUnmarshal(b *testing.B) { + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + b.StopTimer() + b.StartTimer() + if err := readReportFiles(*benchReportPath); err != nil { + b.Fatal(err) + } + } +} + +func readReportFiles(path string) error { + return filepath.Walk(path, + func(p string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + return nil + } + if _, err := MakeFromFile(p); err != nil { + return err + } + return nil + }) +} From cdbc01ecf99ad1d4b125cef57b6f5cdcee27af9f Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Wed, 29 Nov 2017 21:47:32 +0000 Subject: [PATCH 2/3] simplify report.MakeFromFile this new version is less efficient... but not for much longer --- report/marshal.go | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/report/marshal.go b/report/marshal.go index cebcd0b766..794b2bafb1 100644 --- a/report/marshal.go +++ b/report/marshal.go @@ -139,21 +139,7 @@ func MakeFromFile(path string) (rpt Report, _ error) { return rpt, err } - var buf []byte - if gzipped { - r, err := gzip.NewReader(f) - if err != nil { - return rpt, err - } - buf, err = ioutil.ReadAll(r) - } else { - buf, err = ioutil.ReadAll(f) - } - if err != nil { - return rpt, err - } - err = rpt.ReadBytes(buf, handle) - + err = rpt.ReadBinary(f, gzipped, handle) return rpt, err } From 05d5d339c42aaf08108119cb9657764b0db82369 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 24 Mar 2017 09:49:30 +0000 Subject: [PATCH 3/3] Decode reports from a byte buffer Reading and uncompressing the entire message into memory first allows the decoder to avoid memory allocations in field names, etc. --- report/marshal.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/report/marshal.go b/report/marshal.go index 794b2bafb1..f20f30a083 100644 --- a/report/marshal.go +++ b/report/marshal.go @@ -70,10 +70,13 @@ func (rep *Report) ReadBinary(r io.Reader, gzipped bool, codecHandle codec.Handl return err } } - if log.GetLevel() == log.DebugLevel { - r = byteCounter{next: r, count: &uncompressedSize} + // Read everything into memory before decoding: it's faster + buf, err := ioutil.ReadAll(r) + if err != nil { + return err } - if err := codec.NewDecoder(r, codecHandle).Decode(&rep); err != nil { + uncompressedSize = uint64(len(buf)) + if err := rep.ReadBytes(buf, codecHandle); err != nil { return err } log.Debugf(