From fb13c5c56a02c6cd16757f9d8d5a0fd0d1b5e169 Mon Sep 17 00:00:00 2001 From: sneak Date: Sat, 18 May 2024 19:51:45 -0700 Subject: [PATCH] works now, good enough for my use case --- bench.go | 30 +++++++++++++----- bench_test.go | 87 +++++++++++++++++++++++++++++++++------------------ go.mod | 12 ++++++- go.sum | 25 +++++++++++++++ 4 files changed, 116 insertions(+), 38 deletions(-) diff --git a/bench.go b/bench.go index 8274ff9..0e12b0e 100644 --- a/bench.go +++ b/bench.go @@ -7,6 +7,7 @@ import ( "sort" "time" + "github.com/schollz/progressbar/v3" "gonum.org/v1/gonum/stat" ) @@ -48,27 +49,42 @@ func (r TimingResult) String() string { ) } -// TimeFunction runs the given function fn a specified number of times and returns the timing results. -// It supports context for cancellation. -func TimeFunction(ctx context.Context, fn func() error, iterations int) (TimingResult, error) { +// TimeFunction runs the given function fn a specified number of times +// and returns the timing results. It supports context for cancellation. +func TimeFunction( + ctx context.Context, + fn func(), + iterations int, +) (TimingResult, error) { if iterations <= 0 { - return TimingResult{}, errors.New("iterations must be greater than 0") + return TimingResult{}, errors.New( + "iterations must be greater than 0") } times := make([]float64, 0, iterations) startTime := time.Now().UTC() + // Create a progress bar with throttling + bar := progressbar.NewOptions(iterations, + progressbar.OptionSetDescription("Processing..."), + progressbar.OptionShowCount(), + progressbar.OptionShowIts(), + progressbar.OptionSetPredictTime(true), + progressbar.OptionClearOnFinish(), + progressbar.OptionThrottle(100*time.Millisecond), // Update every 100ms + ) + for i := 0; i < iterations; i++ { select { case <-ctx.Done(): return TimingResult{}, ctx.Err() default: iterStart := time.Now().UTC() - if err := fn(); err != nil { - return TimingResult{}, err - } + fn() elapsed := time.Since(iterStart) times = append(times, float64(elapsed)) + + bar.Add(1) } } diff --git a/bench_test.go b/bench_test.go index 222e690..0aa9097 100644 --- a/bench_test.go +++ b/bench_test.go @@ -70,40 +70,12 @@ func quickSort(arr []int) { quickSort(arr[left+1:]) } -// multiplyMatrices performs matrix multiplication of two randomly generated matrices. -func multiplyMatrices(size int) { - matrixA := make([][]int, size) - matrixB := make([][]int, size) - result := make([][]int, size) - - for i := 0; i < size; i++ { - matrixA[i] = make([]int, size) - matrixB[i] = make([]int, size) - result[i] = make([]int, size) - for j := 0; j < size; j++ { - matrixA[i][j] = rand.Intn(100) - matrixB[i][j] = rand.Intn(100) - } - } - - for i := 0; i < size; i++ { - for j := 0; j < size; j++ { - sum := 0 - for k := 0; k < size; k++ { - sum += matrixA[i][k] * matrixB[k][j] - } - result[i][j] = sum - } - } -} - // sampleFunction performs a mix of different operations to introduce variability in runtime. -func sampleFunction() error { +func sampleFunction() { randomSleep() generatePrimes(500 + rand.Intn(1500)) sortRandomSlice(500 + rand.Intn(1500)) multiplyMatrices(20 + rand.Intn(10)) - return nil } func TestTimeFunction(t *testing.T) { @@ -111,7 +83,7 @@ func TestTimeFunction(t *testing.T) { rand.Seed(time.Now().UnixNano()) // Define the number of iterations. - iterations := 1000 + iterations := 700 // Create a context with a timeout for cancellation. ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) @@ -126,3 +98,58 @@ func TestTimeFunction(t *testing.T) { // Print the timing results. t.Logf(result.String()) } + +func multiplyMatrices(size int) int { + matrixA := make([][]int, size) + matrixB := make([][]int, size) + result := make([][]int, size) + + for i := 0; i < size; i++ { + matrixA[i] = make([]int, size) + matrixB[i] = make([]int, size) + result[i] = make([]int, size) + for j := 0; j < size; j++ { + matrixA[i][j] = rand.Intn(10) + matrixB[i][j] = rand.Intn(10) + } + } + + for i := 0; i < size; i++ { + for j := 0; j < size; j++ { + sum := 0 + for k := 0; k < size; k++ { + sum += matrixA[i][k] * matrixB[k][j] + } + result[i][j] = sum + } + } + // sum the result matrix + sum := 0 + for i := 0; i < size; i++ { + for j := 0; j < size; j++ { + sum += result[i][j] + } + } + return sum +} + +func TestMatrixMultiply(t *testing.T) { + // Define the matrix size and number of iterations. + matrixSize := 11 + iterations := 1000000 + + // Create a context with a timeout for cancellation. + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + + // Measure the execution times of the matrix multiplication function. + result, err := TimeFunction(ctx, func() { + _ = multiplyMatrices(matrixSize) + }, iterations) + if err != nil { + t.Fatalf("Error measuring function: %v", err) + } + + // Print the timing results. + t.Logf(result.String()) +} diff --git a/go.mod b/go.mod index 01ad99f..8ca35cf 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,14 @@ module git.eeqj.de/sneak/timingbench go 1.22.2 -require gonum.org/v1/gonum v0.15.0 // indirect +require ( + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect + github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/schollz/progressbar/v3 v3.14.2 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/term v0.20.0 // indirect + gonum.org/v1/gonum v0.15.0 // indirect +) diff --git a/go.sum b/go.sum index 2ea68bd..d5b0f27 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,27 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= +github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0 h1:LiZB1h0GIcudcDci2bxbqI6DXV8bF8POAnArqvRrIyw= +github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0/go.mod h1:F/7q8/HZz+TXjlsoZQQKVYvXTZaFH4QRa3y+j1p7MS0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/schollz/progressbar/v3 v3.14.2 h1:EducH6uNLIWsr560zSV1KrTeUb/wZGAHqyMFIEa99ks= +github.com/schollz/progressbar/v3 v3.14.2/go.mod h1:aQAZQnhF4JGFtRJiw/eobaXpsqpVQAftEQ+hLGXaRc4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo=