From d3dd84b7108ed4a062dced6e1d2d5dd4537c9e57 Mon Sep 17 00:00:00 2001 From: David Symonds Date: Thu, 21 Nov 2019 09:51:39 +1100 Subject: plumbing/object: avoid O(N^2) string building when decoding commit message Most commits have relatively small messages, so this was never noticeable. However, there are some repositories that have semi-automated messages that can get very large (e.g. github.com/riscv/riscv-clang and its riscv-trunk branch), on the order of 109k lines. Changing from string += to using a bytes.Buffer reduces the time for Commit.Decode for that specific case from 35s to 74ms. Signed-off-by: David Symonds --- plumbing/object/commit.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'plumbing') diff --git a/plumbing/object/commit.go b/plumbing/object/commit.go index 6b50934..eb86a01 100644 --- a/plumbing/object/commit.go +++ b/plumbing/object/commit.go @@ -177,6 +177,7 @@ func (c *Commit) Decode(o plumbing.EncodedObject) (err error) { var message bool var pgpsig bool + var msgbuf bytes.Buffer for { line, err := r.ReadBytes('\n') if err != nil && err != io.EOF { @@ -221,13 +222,15 @@ func (c *Commit) Decode(o plumbing.EncodedObject) (err error) { pgpsig = true } } else { - c.Message += string(line) + msgbuf.Write(line) } if err == io.EOF { - return nil + break } } + c.Message = msgbuf.String() + return nil } // Encode transforms a Commit into a plumbing.EncodedObject. -- cgit