Skip to content

Commit e5213a8

Browse files
committed
attempt 7: use preprocessed min, max and sum temps as map value
1 parent 7812da4 commit e5213a8

File tree

4 files changed

+40
-54
lines changed

4 files changed

+40
-54
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@
88
|3|Decouple reading and processing of file content. A buffered goroutine is used to communicate between the two processes.|5:22.83|+57.24|[2babf7d](https://github.com/shraddhaag/1brc/commit/2babf7dda72d92c72722b220b8b663e747075bd7)|
99
|4|Instead of sending each line to the channel, now sending 100 lines chunked together. Also, to minimise garbage collection, not freeing up memory when resetting a slice. |3:41.76|-161.07|[b7b1781](https://github.com/shraddhaag/1brc/commit/b7b1781f58fd258a06940bd6c05eb404c8a14af6)|
1010
|5|Read file in chunks of 100 MB instead of reading line by line. |3:32.62|-9.14|[c26fea4](https://github.com/shraddhaag/1brc/commit/c26fea40019552a7e4fc1c864236f433b1b686f0)|
11-
|6|Convert temperature from `string` to `int64`, process in `int64` and convert to `float64` at the end. |2:51.50|-41.14||
11+
|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)|
12+
|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||

main.go

Lines changed: 38 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package main
22

33
import (
4-
"cmp"
54
"errors"
65
"flag"
76
"fmt"
@@ -12,11 +11,9 @@ import (
1211
"runtime"
1312
"runtime/pprof"
1413
"runtime/trace"
14+
"sort"
1515
"strconv"
1616
"strings"
17-
"sync"
18-
19-
"slices"
2017
)
2118

2219
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
@@ -71,66 +68,44 @@ type result struct {
7168
}
7269

7370
func evaluate(input string) string {
74-
// mapOfTemp, err := readFileLineByLineIntoAMap("./test_cases/measurements-rounding.txt")
75-
// mapOfTemp, err := readFileLineByLineIntoAMap("measurements.txt")
7671
mapOfTemp, err := readFileLineByLineIntoAMap(input)
7772
if err != nil {
7873
panic(err)
7974
}
8075

81-
var resultArr []result
82-
var wg sync.WaitGroup
83-
var mx sync.Mutex
84-
85-
updateResult := func(city, temp string) {
86-
mx.Lock()
87-
defer mx.Unlock()
88-
89-
resultArr = append(resultArr, result{city, temp})
76+
resultArr := make([]string, len(mapOfTemp))
77+
var count int
78+
for city, _ := range mapOfTemp {
79+
resultArr[count] = city
80+
count++
9081
}
9182

92-
for city, temps := range mapOfTemp {
93-
wg.Add(1)
94-
go func(city string, temps []int64) {
95-
defer wg.Done()
96-
var min, max, avg int64
97-
min, max = math.MaxInt64, math.MinInt64
98-
99-
for _, temp := range temps {
100-
if temp < min {
101-
min = temp
102-
}
103-
104-
if temp > max {
105-
max = temp
106-
}
107-
avg += temp
108-
}
109-
110-
updateResult(city, fmt.Sprintf("%.1f/%.1f/%.1f", round(float64(min)/10.0), round(float64(avg)/10.0/float64(len(temps))), round(float64(max)/10.0)))
111-
112-
}(city, temps)
113-
}
114-
115-
wg.Wait()
116-
slices.SortFunc(resultArr, func(i, j result) int {
117-
return cmp.Compare(i.city, j.city)
118-
})
83+
sort.Strings(resultArr)
11984

12085
var stringsBuilder strings.Builder
12186
for _, i := range resultArr {
122-
stringsBuilder.WriteString(fmt.Sprintf("%s=%s, ", i.city, i.temp))
87+
stringsBuilder.WriteString(fmt.Sprintf("%s=%.1f/%.1f/%.1f, ", i,
88+
round(float64(mapOfTemp[i].min)/10.0),
89+
round(float64(mapOfTemp[i].sum)/10.0/float64(mapOfTemp[i].count)),
90+
round(float64(mapOfTemp[i].max)/10.0)))
12391
}
12492
return stringsBuilder.String()[:stringsBuilder.Len()-2]
12593
}
12694

127-
func readFileLineByLineIntoAMap(filepath string) (map[string][]int64, error) {
95+
type cityTemperatureInfo struct {
96+
count int64
97+
min int64
98+
max int64
99+
sum int64
100+
}
101+
102+
func readFileLineByLineIntoAMap(filepath string) (map[string]cityTemperatureInfo, error) {
128103
file, err := os.Open(filepath)
129104
if err != nil {
130105
panic(err)
131106
}
132107

133-
mapOfTemp := make(map[string][]int64)
108+
mapOfTemp := make(map[string]cityTemperatureInfo)
134109

135110
chanOwner := func() <-chan []string {
136111
resultStream := make(chan []string, 100)
@@ -170,21 +145,31 @@ func readFileLineByLineIntoAMap(filepath string) (map[string][]int64, error) {
170145
}
171146
city := text[:index]
172147
temp := convertStringToInt64(text[index+1:])
173-
if _, ok := mapOfTemp[city]; ok {
174-
mapOfTemp[city] = append(mapOfTemp[city], temp)
148+
if val, ok := mapOfTemp[city]; ok {
149+
val.count++
150+
val.sum += temp
151+
if temp < val.min {
152+
val.min = temp
153+
}
154+
155+
if temp > val.max {
156+
val.max = temp
157+
}
158+
mapOfTemp[city] = val
175159
} else {
176-
mapOfTemp[city] = []int64{temp}
160+
mapOfTemp[city] = cityTemperatureInfo{
161+
count: 1,
162+
min: temp,
163+
max: temp,
164+
sum: temp,
165+
}
177166
}
178167
}
179168
}
169+
// fmt.Println(mapOfTemp)
180170
return mapOfTemp, nil
181171
}
182172

183-
type cityTemp struct {
184-
city string
185-
temp float64
186-
}
187-
188173
func convertStringToInt64(input string) int64 {
189174
input = input[:len(input)-2] + input[len(input)-1:]
190175
output, _ := strconv.ParseInt(input, 10, 64)

profiles/cpu-int64.prof

18 KB
Binary file not shown.

profiles/cpu-preprocess.prof

16.1 KB
Binary file not shown.

0 commit comments

Comments
 (0)