diff --git a/.gitignore b/.gitignore index b26bca2..9c04c0b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -benchmark \ No newline at end of file +benchmark +.vscode \ No newline at end of file diff --git a/README.md b/README.md index cd46221..52eae33 100644 --- a/README.md +++ b/README.md @@ -13,5 +13,17 @@ The above command will generate two files that will be used for profiling the pr To use the generated files for profiling you have to run: `go tool pprof cpu00.pprof` +For memory +`go test -bench . -benchtime=10x -run ^$ -memprofile mem00.pprof` + +`go tool pprof -alloc_space mem00.pprof` + This will start an interactive cli session where you can view more details about the functions running in the program -Inside that interactive cli session you can use the `top` and `list` commands to see details of the functions that are running \ No newline at end of file +Inside that interactive cli session you can use the `top` and `list` commands to see details of the functions that are running + + +For tracing: + +`go test -bench . -benchtime=10x -run ^$ -trace trace01.out` + +`go tool trace trace01.out` \ No newline at end of file diff --git a/cpu00max.pprof b/cpu00max.pprof new file mode 100644 index 0000000..041eee6 Binary files /dev/null and b/cpu00max.pprof differ diff --git a/csv.go b/csv.go index 71014fe..6cf8939 100644 --- a/csv.go +++ b/csv.go @@ -4,6 +4,7 @@ import ( "encoding/csv" "fmt" "io" + "sort" "strconv" ) @@ -21,6 +22,16 @@ func avg(data []float64) float64 { return sum(data) / float64(len(data)) } +func min(data []float64) float64 { + sort.Float64s(data) + return data[0] +} + +func max(data []float64) float64 { + sort.Float64s(data) + return data[len(data)-1] +} + func csv2float(r io.Reader, column int) ([]float64, error) { cr := csv.NewReader(r) // set this to reuse the same slice for each read diff --git a/csv_test.go b/csv_test.go index 3324326..1f6299f 100644 --- a/csv_test.go +++ b/csv_test.go @@ -23,11 +23,13 @@ func TestOperations(t *testing.T) { }{ {"Sum", sum, []float64{300, 85.927, -30, 436}}, {"Avg", avg, []float64{37.5, 6.609769230769231, -15, 72.666666666666666}}, + {"Min", min, []float64{10, 2.2, -20, 37}}, + {"Max", max, []float64{100, 12.287, -10, 129}}, } for _, tc := range testCases { for k, exp := range tc.exp { - name := fmt.Sprintf("%sData%d", tc.name, k) + name := fmt.Sprintf("%s Data %d", tc.name, k) t.Run(name, func(t *testing.T) { res := tc.op(data[k]) // comparing floats might not be the best solution diff --git a/main.go b/main.go index c88544a..ad6752c 100644 --- a/main.go +++ b/main.go @@ -34,6 +34,10 @@ func run(filenames []string, op string, column int, out io.Writer) error { opFunc = sum case "avg": opFunc = avg + case "min": + opFunc = min + case "max": + opFunc = max default: return fmt.Errorf("%w: %s", ErrInvalidOperation, op) } @@ -82,7 +86,9 @@ func run(filenames []string, op string, column int, out io.Writer) error { wg.Wait() close(doneCh) }() - + // TODO try to improve the performance of min and max + // by running the functions in multiple gorutines + // or by trying to run the functions for each file that is read for { select { case err := <-errCh: diff --git a/main_test.go b/main_test.go index 5e91040..58d101c 100644 --- a/main_test.go +++ b/main_test.go @@ -76,7 +76,7 @@ func BenchmarkRun(b *testing.B) { // reset the time before running the benchmark loop b.ResetTimer() for i := 0; i < b.N; i++ { - if err := run(filenames, "avg", 2, io.Discard); err != nil { + if err := run(filenames, "max", 2, io.Discard); err != nil { b.Error(err) } } diff --git a/mem00max.pprof b/mem00max.pprof new file mode 100644 index 0000000..d4f1708 Binary files /dev/null and b/mem00max.pprof differ diff --git a/trace03.out b/trace03.out new file mode 100644 index 0000000..81a651a Binary files /dev/null and b/trace03.out differ