Skip to content

Commit 12e4efd

Browse files
committed
go: Reduce Decode time by a further 35%
Use a bool array to look up valid characters instead of a switch. This is far more performant as switch-case becomes essentially a long list of if statements, whereas a lookup in a bool array is constant-time.
1 parent 0fb4f5a commit 12e4efd

1 file changed

Lines changed: 12 additions & 5 deletions

File tree

go/olc.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@ func (area CodeArea) Center() (lat, lng float64) {
7575
math.Min(area.LngLo+(area.LngHi-area.LngLo)/2, lngMax)
7676
}
7777

78+
var inAlphabet = [128]bool{
79+
'2': true, '3': true, '4': true, '5': true, '6': true, '7': true, '8': true, '9': true,
80+
'C': true, 'F': true, 'G': true, 'H': true, 'J': true, 'M': true, 'P': true, 'Q': true,
81+
'R': true, 'V': true, 'W': true, 'X': true,
82+
'c': true, 'f': true, 'g': true, 'h': true, 'j': true, 'm': true, 'p': true, 'q': true,
83+
'r': true, 'v': true, 'w': true, 'x': true,
84+
}
85+
7886
// Check checks whether the passed string is a valid OLC code.
7987
// It could be a full code (8FVC9G8F+6W), a padded code (8FVC0000+) or a code fragment (9G8F+6W).
8088
func Check(code string) error {
@@ -101,14 +109,13 @@ func Check(code string) error {
101109
return fmt.Errorf("%c after zero @%d", r, i)
102110
}
103111

104-
if '2' <= r && r <= '9' {
112+
if r > 128 {
113+
return fmt.Errorf("invalid char %c @%d", r, i)
114+
}
115+
if inAlphabet[r] {
105116
continue
106117
}
107118
switch r {
108-
case 'C', 'F', 'G', 'H', 'J', 'M', 'P', 'Q', 'R', 'V', 'W', 'X',
109-
// Processing of Plus Codes must be case insensitive.
110-
'c', 'f', 'g', 'h', 'j', 'm', 'p', 'q', 'r', 'v', 'w', 'x':
111-
continue
112119
case Separator:
113120
// In addition to the above characters, a full Open Location Code can include a single "+" as a separator after the eighth digit.
114121
if firstSep != -1 {

0 commit comments

Comments
 (0)