aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaulo Gomes <pjbgf@linux.com>2022-11-07 14:42:00 +0000
committerPaulo Gomes <pjbgf@linux.com>2022-11-07 14:42:00 +0000
commitffa7e69efb8c4ba8d4e08ec4c65e49e2228fd88b (patch)
treea784f0a4b677abc00247638e600f5efef1c44dfc
parent123cdde6f2f6282cb779e03745d384833ac1265b (diff)
downloadgo-git-ffa7e69efb8c4ba8d4e08ec4c65e49e2228fd88b.tar.gz
Optimise Reference.String()
Decreases allocations and bytes per operation by using string builder with a predefined size. One additional allocation has been removed by using its own implementation of Strings(). The reason behind this was due to the fact the calls to .String() are more recurrent than .Strings() and the performance impact was worth the code duplication. Benchmark results: cpu: 11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz name old time/op new time/op delta ReferenceStringSymbolic-16 140ns ± 4% 40ns ± 9% -71.19% (p=0.008 n=5+5) ReferenceStringHash-16 174ns ±14% 85ns ± 4% -51.13% (p=0.008 n=5+5) ReferenceStringInvalid-16 48.9ns ± 2% 1.5ns ± 3% -96.96% (p=0.008 n=5+5) name old alloc/op new alloc/op delta ReferenceStringSymbolic-16 88.0B ± 0% 32.0B ± 0% -63.64% (p=0.008 n=5+5) ReferenceStringHash-16 176B ± 0% 144B ± 0% -18.18% (p=0.008 n=5+5) ReferenceStringInvalid-16 0.00B 0.00B ~ (all equal) name old allocs/op new allocs/op delta ReferenceStringSymbolic-16 4.00 ± 0% 1.00 ± 0% -75.00% (p=0.008 n=5+5) ReferenceStringHash-16 5.00 ± 0% 3.00 ± 0% -40.00% (p=0.008 n=5+5) ReferenceStringInvalid-16 0.00 0.00 ~ (all equal) Signed-off-by: Paulo Gomes <pjbgf@linux.com>
-rw-r--r--plumbing/reference.go19
-rw-r--r--plumbing/reference_test.go24
2 files changed, 40 insertions, 3 deletions
diff --git a/plumbing/reference.go b/plumbing/reference.go
index deb5067..eef11e8 100644
--- a/plumbing/reference.go
+++ b/plumbing/reference.go
@@ -204,6 +204,21 @@ func (r *Reference) Strings() [2]string {
}
func (r *Reference) String() string {
- s := r.Strings()
- return fmt.Sprintf("%s %s", s[1], s[0])
+ ref := ""
+ switch r.Type() {
+ case HashReference:
+ ref = r.Hash().String()
+ case SymbolicReference:
+ ref = symrefPrefix + r.Target().String()
+ default:
+ return ""
+ }
+
+ name := r.Name().String()
+ var v strings.Builder
+ v.Grow(len(ref) + len(name) + 1)
+ v.WriteString(ref)
+ v.WriteString(" ")
+ v.WriteString(name)
+ return v.String()
}
diff --git a/plumbing/reference_test.go b/plumbing/reference_test.go
index b3ccf53..e69076f 100644
--- a/plumbing/reference_test.go
+++ b/plumbing/reference_test.go
@@ -1,6 +1,10 @@
package plumbing
-import . "gopkg.in/check.v1"
+import (
+ "testing"
+
+ . "gopkg.in/check.v1"
+)
type ReferenceSuite struct{}
@@ -98,3 +102,21 @@ func (s *ReferenceSuite) TestIsTag(c *C) {
r := ReferenceName("refs/tags/v3.1.")
c.Assert(r.IsTag(), Equals, true)
}
+
+func benchMarkReferenceString(r *Reference, b *testing.B) {
+ for n := 0; n < b.N; n++ {
+ r.String()
+ }
+}
+
+func BenchmarkReferenceStringSymbolic(b *testing.B) {
+ benchMarkReferenceString(NewSymbolicReference("v3.1.1", "refs/tags/v3.1.1"), b)
+}
+
+func BenchmarkReferenceStringHash(b *testing.B) {
+ benchMarkReferenceString(NewHashReference("v3.1.1", NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")), b)
+}
+
+func BenchmarkReferenceStringInvalid(b *testing.B) {
+ benchMarkReferenceString(&Reference{}, b)
+}