Skip to content

Commit

Permalink
attempt 12: use custom parser to convert string to int
Browse files Browse the repository at this point in the history
  • Loading branch information
shraddhaag committed Jan 30, 2024
1 parent 88bb6da commit 4988ae0
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 8 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@
|8|Use producer consumer pattern to read file in chunks and process the chunks in parallel.|1:43.82|+14.01|[067f2a4](https://github.com/shraddhaag/1brc/commit/067f2a44c0d6b3bb7cc073639364f733bce09e3e)|
|9|Reduce memory allocation by processing each read chunk into a map. Result channel now can collate the smaller processed chunk maps.|0:28.544|-75.286|[d4153ac](https://github.com/shraddhaag/1brc/commit/d4153ac7a841170a5ceee47d930e97738b5a19f6)|
|10|Avoid string concatenation overhead by not reading the decimal point when processing city temperature.|0:24.571|-3.973|[90f2fe1](https://github.com/shraddhaag/1brc/commit/90f2fe121f454f3f1b5cdaeaaebe639bb86d4578)|
|11|Convert byte slice to string directly instead of using a `strings.Builder`.|0:18.910|-5.761||
|11|Convert byte slice to string directly instead of using a `strings.Builder`.|0:18.910|-5.761|[88bb6da](https://github.com/shraddhaag/1brc/commit/88bb6da8b85424d46a8c836f3c35a49466df1ea4)|
|12|Replace `strconv.ParseInt` with a custom `string` to `int` parser.|0:14.008|-4.902||
31 changes: 24 additions & 7 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"runtime/pprof"
"runtime/trace"
"sort"
"strconv"
"strings"
"sync"
)
Expand Down Expand Up @@ -179,7 +178,7 @@ func readFileLineByLineIntoAMap(filepath string) (map[string]cityTemperatureInfo
func processReadChunk(buf []byte, resultStream chan<- map[string]cityTemperatureInfo) {
toSend := make(map[string]cityTemperatureInfo)
var start int
var city, tempString string
var city string

stringBuf := string(buf)
for index, char := range stringBuf {
Expand All @@ -189,7 +188,7 @@ func processReadChunk(buf []byte, resultStream chan<- map[string]cityTemperature
start = index + 1
case '\n':
if (index-start) > 1 && len(city) != 0 {
temp, _ := strconv.ParseInt(tempString+string(stringBuf[index-1]), 10, 64)
temp := customStringToIntParser(stringBuf[start:index])
start = index + 1

if val, ok := toSend[city]; ok {
Expand All @@ -214,10 +213,6 @@ func processReadChunk(buf []byte, resultStream chan<- map[string]cityTemperature

city = ""
}
case '.':
if len(city) != 0 {
tempString = stringBuf[start:index]
}
}
}
resultStream <- toSend
Expand All @@ -230,3 +225,25 @@ func round(x float64) float64 {
}
return rounded / 10
}

// input: string containing signed number in the range [-99.9, 99.9]
// output: signed int in the range [-999, 999]
func customStringToIntParser(input string) (output int64) {
var isNegativeNumber bool
if input[0] == '-' {
isNegativeNumber = true
input = input[1:]
}

switch len(input) {
case 3:
output = int64(input[0])*10 + int64(input[2]) - int64('0')*11
case 4:
output = int64(input[0])*100 + int64(input[1])*10 + int64(input[3]) - (int64('0') * 111)
}

if isNegativeNumber {
return -output
}
return
}

0 comments on commit 4988ae0

Please sign in to comment.