Skip to content

Commit 9d9badb

Browse files
committed
Caching bytes array to increase access speed
1 parent 4907abe commit 9d9badb

File tree

4 files changed

+68
-63
lines changed

4 files changed

+68
-63
lines changed

benchmark_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ func BenchmarkVersionParser(b *testing.B) {
6868
res := &Version{}
6969
for i := 0; i < b.N; i++ {
7070
for _, v := range list {
71-
parseInto([]byte(v), res)
71+
res.raw = v
72+
res.bytes = []byte(v)
73+
parse(res)
7274
}
7375
}
7476

@@ -82,7 +84,7 @@ func BenchmarkVersionParser(b *testing.B) {
8284
// BenchmarkVersionParser-12 188611 7715 ns/op 8557 B/op 51 allocs/op
8385

8486
// Results for v0.12.0: \o/
85-
// BenchmarkVersionParser-12 1298325 912.9 ns/op 0 B/op 0 allocs/op
87+
// BenchmarkVersionParser-12 479626 3719 ns/op 616 B/op 51 allocs/op
8688
}
8789

8890
func BenchmarkVersionComparator(b *testing.B) {
@@ -112,6 +114,6 @@ func BenchmarkVersionComparator(b *testing.B) {
112114
// Results for v0.11.0:
113115
// BenchmarkVersionComparator-12 74793 17347 ns/op 0 B/op 0 allocs/op
114116

115-
// Results for v0.12.0: :-|
116-
// BenchmarkVersionComparator-12 74320 16223 ns/op 0 B/op 0 allocs/op
117+
// Results for v0.12.0: :-)
118+
// BenchmarkVersionComparator-12 80622 14659 ns/op 0 B/op 0 allocs/op
117119
}

parser.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,18 @@ func MustParse(inVersion string) *Version {
2222
// Parse parse a version string
2323
func Parse(inVersion string) (*Version, error) {
2424
result := &Version{
25-
raw: inVersion,
25+
raw: inVersion,
26+
bytes: []byte(inVersion),
2627
}
27-
if err := parseInto([]byte(inVersion), result); err != nil {
28+
if err := parse(result); err != nil {
2829
return nil, err
2930
}
3031
return result, nil
3132
}
3233

33-
func parseInto(in []byte, result *Version) error {
34+
func parse(result *Version) error {
3435
// Setup parsing harness
36+
in := result.bytes
3537
inLen := len(in)
3638
currIdx := -1
3739
var curr byte

version.go

Lines changed: 52 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package semver
99
// Version contains the results of parsed version string
1010
type Version struct {
1111
raw string
12+
bytes []byte
1213
major int
1314
minor int
1415
patch int
@@ -70,7 +71,7 @@ func (v *Version) Normalize() {
7071
}
7172
}
7273

73-
func compareNumber(a, b string) int {
74+
func compareNumber(a, b []byte) int {
7475
la := len(a)
7576
lb := len(b)
7677
if la == lb {
@@ -101,7 +102,7 @@ func compareAlpha(a, b []byte) int {
101102
return 0
102103
}
103104

104-
var zero = "0"
105+
var zero = []byte("0")
105106

106107
// CompareTo compares the Version with the one passed as parameter.
107108
// Returns -1, 0 or 1 if the version is respectively less than, equal
@@ -114,23 +115,25 @@ func (v *Version) CompareTo(u *Version) int {
114115
// comparing each of these identifiers from left to right as follows: Major, minor,
115116
// and patch versions are always compared numerically.
116117
// Example: 1.0.0 < 2.0.0 < 2.1.0 < 2.1.1.
117-
vMajor := zero[:]
118-
if v.major > 0 {
119-
vMajor = v.raw[:v.major]
118+
vMajorValue := zero[:]
119+
vMajor := v.major
120+
if vMajor > 0 {
121+
vMajorValue = v.bytes[:vMajor]
120122
}
121-
uMajor := zero[:]
122-
if u.major > 0 {
123-
uMajor = u.raw[:u.major]
123+
uMajorValue := zero[:]
124+
uMajor := u.major
125+
if uMajor > 0 {
126+
uMajorValue = u.bytes[:uMajor]
124127
}
125128
{
126-
la := len(vMajor)
127-
lb := len(uMajor)
129+
la := len(vMajorValue)
130+
lb := len(uMajorValue)
128131
if la == lb {
129-
for i := range vMajor {
130-
if vMajor[i] == uMajor[i] {
132+
for i := range vMajorValue {
133+
if vMajorValue[i] == uMajorValue[i] {
131134
continue
132135
}
133-
if vMajor[i] > uMajor[i] {
136+
if vMajorValue[i] > uMajorValue[i] {
134137
return 1
135138
}
136139
return -1
@@ -141,26 +144,25 @@ func (v *Version) CompareTo(u *Version) int {
141144
return -1
142145
}
143146
}
144-
vMinor := zero[:]
145-
if v.minor > v.major {
146-
vMinor = v.raw[v.major+1 : v.minor]
147+
vMinorValue := zero[:]
148+
vMinor := v.minor
149+
if vMinor > vMajor {
150+
vMinorValue = v.bytes[vMajor+1 : vMinor]
147151
}
148-
uMinor := zero[:]
149-
if u.minor > u.major {
150-
uMinor = u.raw[u.major+1 : u.minor]
152+
uMinorValue := zero[:]
153+
uMinor := u.minor
154+
if uMinor > uMajor {
155+
uMinorValue = u.bytes[uMajor+1 : uMinor]
151156
}
152-
// if cmp := compareNumber(vMinor, uMinor); cmp != 0 {
153-
// return cmp
154-
// }
155157
{
156-
la := len(vMinor)
157-
lb := len(uMinor)
158+
la := len(vMinorValue)
159+
lb := len(uMinorValue)
158160
if la == lb {
159-
for i := range vMinor {
160-
if vMinor[i] == uMinor[i] {
161+
for i := range vMinorValue {
162+
if vMinorValue[i] == uMinorValue[i] {
161163
continue
162164
}
163-
if vMinor[i] > uMinor[i] {
165+
if vMinorValue[i] > uMinorValue[i] {
164166
return 1
165167
}
166168
return -1
@@ -171,26 +173,25 @@ func (v *Version) CompareTo(u *Version) int {
171173
return -1
172174
}
173175
}
174-
vPatch := zero[:]
175-
if v.patch > v.minor {
176-
vPatch = v.raw[v.minor+1 : v.patch]
176+
vPatchValue := zero[:]
177+
vPatch := v.patch
178+
if vPatch > vMinor {
179+
vPatchValue = v.bytes[vMinor+1 : vPatch]
177180
}
178-
uPatch := zero[:]
179-
if u.patch > u.minor {
180-
uPatch = u.raw[u.minor+1 : u.patch]
181+
uPatchValue := zero[:]
182+
uPatch := u.patch
183+
if uPatch > uMinor {
184+
uPatchValue = u.bytes[uMinor+1 : uPatch]
181185
}
182-
// if cmp := compareNumber(vPatch, uPatch); cmp != 0 {
183-
// return cmp
184-
// }
185186
{
186-
la := len(vPatch)
187-
lb := len(uPatch)
187+
la := len(vPatchValue)
188+
lb := len(uPatchValue)
188189
if la == lb {
189-
for i := range vPatch {
190-
if vPatch[i] == uPatch[i] {
190+
for i := range vPatchValue {
191+
if vPatchValue[i] == uPatchValue[i] {
191192
continue
192193
}
193-
if vPatch[i] > uPatch[i] {
194+
if vPatchValue[i] > uPatchValue[i] {
194195
return 1
195196
}
196197
return -1
@@ -203,7 +204,7 @@ func (v *Version) CompareTo(u *Version) int {
203204
}
204205

205206
// if both versions have no pre-release, they are equal
206-
if v.prerelease == v.patch && u.prerelease == u.patch {
207+
if v.prerelease == vPatch && u.prerelease == uPatch {
207208
return 0
208209
}
209210

@@ -212,11 +213,11 @@ func (v *Version) CompareTo(u *Version) int {
212213
// Example: 1.0.0-alpha < 1.0.0.
213214

214215
// if v has no pre-release, it's greater than u
215-
if v.prerelease == v.patch {
216+
if v.prerelease == vPatch {
216217
return 1
217218
}
218219
// if u has no pre-release, it's greater than v
219-
if u.prerelease == u.patch {
220+
if u.prerelease == uPatch {
220221
return -1
221222
}
222223

@@ -369,26 +370,26 @@ func (v *Version) CompatibleWith(u *Version) bool {
369370
}
370371
vMajor := zero[:]
371372
if v.major > 0 {
372-
vMajor = v.raw[:v.major]
373+
vMajor = v.bytes[:v.major]
373374
}
374375
uMajor := zero[:]
375376
if u.major > 0 {
376-
uMajor = u.raw[:u.major]
377+
uMajor = u.bytes[:u.major]
377378
}
378379
majorEquals := compareNumber(vMajor, uMajor) == 0
379-
if v.major > 0 && v.raw[0] != '0' {
380+
if v.major > 0 && v.bytes[0] != '0' {
380381
return majorEquals
381382
}
382383
if !majorEquals {
383384
return false
384385
}
385386
vMinor := zero[:]
386387
if v.minor > v.major {
387-
vMinor = v.raw[v.major+1 : v.minor]
388+
vMinor = v.bytes[v.major+1 : v.minor]
388389
}
389390
uMinor := zero[:]
390391
if u.minor > u.major {
391-
uMinor = u.raw[u.major+1 : u.minor]
392+
uMinor = u.bytes[u.major+1 : u.minor]
392393
}
393394
minorEquals := compareNumber(vMinor, uMinor) == 0
394395
if vMinor[0] != '0' {
@@ -399,11 +400,11 @@ func (v *Version) CompatibleWith(u *Version) bool {
399400
}
400401
vPatch := zero[:]
401402
if v.patch > v.minor {
402-
vPatch = v.raw[v.minor+1 : v.patch]
403+
vPatch = v.bytes[v.minor+1 : v.patch]
403404
}
404405
uPatch := zero[:]
405406
if u.patch > u.minor {
406-
uPatch = u.raw[u.minor+1 : u.patch]
407+
uPatch = u.bytes[u.minor+1 : u.patch]
407408
}
408409
return compareNumber(vPatch, uPatch) == 0
409410
}

version_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,14 +221,14 @@ func TestNilVersionString(t *testing.T) {
221221

222222
func TestCompareNumbers(t *testing.T) {
223223
// ==
224-
require.Zero(t, compareNumber("0", "0"))
225-
require.Zero(t, compareNumber("5", "5"))
226-
require.Zero(t, compareNumber("15", "15"))
224+
require.Zero(t, compareNumber([]byte("0"), []byte("0")))
225+
require.Zero(t, compareNumber([]byte("5"), []byte("5")))
226+
require.Zero(t, compareNumber([]byte("15"), []byte("15")))
227227

228228
// >
229229
testGreater := func(a, b string) {
230-
require.Positive(t, compareNumber(a, b), `compareNumber("%s","%s") is not positive`, a, b)
231-
require.Negative(t, compareNumber(b, a), `compareNumber("%s","%s") is not negative`, b, a)
230+
require.Positive(t, compareNumber([]byte(a), []byte(b)), `compareNumber("%s","%s") is not positive`, a, b)
231+
require.Negative(t, compareNumber([]byte(b), []byte(a)), `compareNumber("%s","%s") is not negative`, b, a)
232232
}
233233
testGreater("1", "")
234234
testGreater("1", "0")

0 commit comments

Comments
 (0)