Skip to content

Commit

Permalink
Optimized IntStrings/UintStrings function
Browse files Browse the repository at this point in the history
This makes the parse functions using these functions or Extract(U)Ints around 5-6 times faster
  • Loading branch information
ictrobot committed Dec 22, 2023
1 parent 273ff10 commit 7ea96e9
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 6 deletions.
40 changes: 34 additions & 6 deletions internal/util/parse/int.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@ package parse

import (
"github.com/samber/lo"
"regexp"
"strconv"
)

var uintRegexp = regexp.MustCompile(`[0-9]+`)
var intRegexp = regexp.MustCompile(`[+-]?[0-9]+`)

func Int(s string) int {
v, err := strconv.ParseInt(s, 10, strconv.IntSize)
return int(lo.Must(v, err, "parsing int"))
Expand Down Expand Up @@ -140,7 +136,7 @@ func Uint64s(s []string) []uint64 {
}

func IntStrings(s string) []string {
return intRegexp.FindAllString(s, -1)
return intStrings(s, true)
}

func ExtractInts(s string) []int {
Expand All @@ -152,7 +148,7 @@ func ExtractInt64s(s string) []int64 {
}

func UintStrings(s string) []string {
return uintRegexp.FindAllString(s, -1)
return intStrings(s, false)
}

func ExtractUints(s string) []uint {
Expand All @@ -172,3 +168,35 @@ func ExtractDigits(s string) []int {
}
return r
}

func intStrings(s string, signed bool) []string {
if s == "" {
return nil
}

i := 0
results := make([]string, 0, len(s)/2)
for i < len(s) {
for i < len(s) && (s[i] < '0' || s[i] > '9') {
i++
}

if i >= len(s) {
break
}

j := i + 1
for j < len(s) && s[j] >= '0' && s[j] <= '9' {
j++
}

if signed && i > 0 && (s[i-1] == '-' || s[i-1] == '+') {
i--
}

results = append(results, s[i:j])
i = j
}

return results
}
8 changes: 8 additions & 0 deletions internal/util/parse/int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,10 @@ func TestUint64s(t *testing.T) {
})
}

func TestIntStrings(t *testing.T) {
assert.Equal(t, []string{"1", "+123", "-233", "-2", "+4", "5"}, IntStrings("1 +123 -233 +-2 -+4 .5"))
}

func TestExtractInts(t *testing.T) {
assert.Equal(t, []int{1, -2147483648, 2, 2147483647}, ExtractInts("1: -2147483648 \n 2 abc 2147483647\n"))
}
Expand All @@ -293,6 +297,10 @@ func TestExtractInt64s(t *testing.T) {
assert.Equal(t, []int64{2, -9223372036854775808, 2, 9223372036854775807}, ExtractInt64s("2: -9223372036854775808 \n 2 abc 9223372036854775807\n"))
}

func TestUintStrings(t *testing.T) {
assert.Equal(t, []string{"1", "123", "233", "2", "4", "5"}, UintStrings("1 +123 -233 +-2 -+4 .5"))
}

func TestExtractUints(t *testing.T) {
assert.Equal(t, []uint{3, 0, 2, 4294967295}, ExtractUints("3: 0 \n 2 abc 4294967295\n"))
}
Expand Down

0 comments on commit 7ea96e9

Please sign in to comment.