Skip to content

Commit b59dd64

Browse files
author
ruanyingjie
committed
remove regex to improve performance
1 parent 9cedb42 commit b59dd64

File tree

2 files changed

+41
-35
lines changed

2 files changed

+41
-35
lines changed

bytes/bytes.go

+28-33
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ package bytes
22

33
import (
44
"fmt"
5-
"regexp"
65
"strconv"
6+
"unicode"
77
)
88

99
type (
@@ -22,8 +22,7 @@ const (
2222
)
2323

2424
var (
25-
pattern = regexp.MustCompile(`(?i)^(-?\d+)([KMGTP]B?|B)$`)
26-
global = New()
25+
global = New()
2726
)
2827

2928
// New creates a Bytes instance.
@@ -43,9 +42,6 @@ func (*Bytes) Format(b int64) string {
4342
case b < MB:
4443
value /= KB
4544
multiple = "KB"
46-
case b < MB:
47-
value /= KB
48-
multiple = "KB"
4945
case b < GB:
5046
value /= MB
5147
multiple = "MB"
@@ -59,40 +55,39 @@ func (*Bytes) Format(b int64) string {
5955
value /= PB
6056
multiple = "PB"
6157
}
62-
63-
return fmt.Sprintf("%.02f%s", value, multiple)
58+
return strconv.FormatFloat(value, 'f', 2, 64) + multiple
6459
}
6560

6661
// Parse parses human readable bytes string to bytes integer.
6762
// For example, 6GB (6G is also valid) will return 6442450944.
68-
func (*Bytes) Parse(value string) (i int64, err error) {
69-
parts := pattern.FindStringSubmatch(value)
70-
if len(parts) < 3 {
71-
return 0, fmt.Errorf("error parsing value=%s", value)
72-
}
73-
bytesString := parts[1]
74-
multiple := parts[2]
75-
bytes, err := strconv.ParseInt(bytesString, 10, 64)
76-
if err != nil {
77-
return
78-
}
63+
func (*Bytes) Parse(value string) (int64, error) {
64+
for i, s := range value {
65+
if unicode.IsLetter(s) {
66+
bytesString, multiple := value[:i], value[i:]
67+
68+
bytes, err := strconv.ParseInt(bytesString, 10, 64)
69+
if err != nil {
70+
return 0, err
71+
}
7972

80-
switch multiple {
81-
case "B":
82-
return bytes * B, nil
83-
case "K", "KB":
84-
return bytes * KB, nil
85-
case "M", "MB":
86-
return bytes * MB, nil
87-
case "G", "GB":
88-
return bytes * GB, nil
89-
case "T", "TB":
90-
return bytes * TB, nil
91-
case "P", "PB":
92-
return bytes * PB, nil
73+
switch multiple {
74+
case "B":
75+
return bytes * B, nil
76+
case "K", "KB":
77+
return bytes * KB, nil
78+
case "M", "MB":
79+
return bytes * MB, nil
80+
case "G", "GB":
81+
return bytes * GB, nil
82+
case "T", "TB":
83+
return bytes * TB, nil
84+
case "P", "PB":
85+
return bytes * PB, nil
86+
}
87+
}
9388
}
9489

95-
return
90+
return 0, fmt.Errorf("error parsing value=%s", value)
9691
}
9792

9893
// Format wraps global Bytes's Format function.

bytes/bytes_test.go

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
package bytes
22

33
import (
4-
"testing"
5-
64
"github.com/stretchr/testify/assert"
5+
"testing"
76
)
87

98
func TestBytesFormat(t *testing.T) {
@@ -89,3 +88,15 @@ func TestBytesParse(t *testing.T) {
8988
assert.Equal(t, int64(10133099161583616), b)
9089
}
9190
}
91+
92+
func BenchmarkBytes_Format(b *testing.B) {
93+
for i := 0; i < b.N; i++ {
94+
Format(7323232398434)
95+
}
96+
}
97+
98+
func BenchmarkBytes_Parse(b *testing.B) {
99+
for i := 0; i < b.N; i++ {
100+
Parse("90000PB")
101+
}
102+
}

0 commit comments

Comments
 (0)