diff --git a/README.md b/README.md index 92cac43..244fb5e 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,5 @@ |6|Convert temperature from `string` to `int64`, process in `int64` and convert to `float64` at the end. |2:51.50|-41.14|[7812da4](https://github.com/shraddhaag/1brc/commit/7812da4d0be07dd4686d5f9b9df1e93b08cd0dd1)| |7|In the city <> temperatures map, replaced the value for each key (city) to preprocessed min, max, count and sum of all temperatures instead of storing all recorded temperatures for the city.|1:39.81|-71.79|[e5213a8](https://github.com/shraddhaag/1brc/commit/e5213a836b17bec0a858474a11f07c902e724bba)| |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|| \ No newline at end of file +|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.752|-3.792|| \ No newline at end of file diff --git a/main.go b/main.go index 7d66a20..61f3735 100644 --- a/main.go +++ b/main.go @@ -176,24 +176,19 @@ func readFileLineByLineIntoAMap(filepath string) (map[string]cityTemperatureInfo return mapOfTemp, nil } -func convertStringToInt64(input string) int64 { - input = input[:len(input)-2] + input[len(input)-1:] - output, _ := strconv.ParseInt(input, 10, 64) - return output -} - func processReadChunk(buf []byte, resultStream chan<- map[string]cityTemperatureInfo) { var stringsBuilder strings.Builder toSend := make(map[string]cityTemperatureInfo) var city string for _, char := range buf { - if char == ';' { + switch char { + case ';': city = stringsBuilder.String() stringsBuilder.Reset() - } else if char == '\n' { + case '\n': if stringsBuilder.Len() != 0 && len(city) != 0 { - temp := convertStringToInt64(stringsBuilder.String()) + temp, _ := strconv.ParseInt(stringsBuilder.String(), 10, 64) stringsBuilder.Reset() if val, ok := toSend[city]; ok { @@ -215,8 +210,13 @@ func processReadChunk(buf []byte, resultStream chan<- map[string]cityTemperature sum: temp, } } + city = "" + } + case '.': + if len(city) != 0 { + continue } - } else { + default: stringsBuilder.WriteByte(char) } } diff --git a/profiles/cpu-remove-slice.prof b/profiles/cpu-remove-slice.prof new file mode 100644 index 0000000..144b701 Binary files /dev/null and b/profiles/cpu-remove-slice.prof differ