Compare commits
	
		
			2 Commits
		
	
	
		
			81b25d1421
			...
			fb13c5c56a
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| fb13c5c56a | |||
| 82cfc3c88e | 
							
								
								
									
										7
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								Makefile
									
									
									
									
									
								
							| @ -2,3 +2,10 @@ default: test | ||||
| 
 | ||||
| test: | ||||
| 	go test -v -count=1 ./... | ||||
| 
 | ||||
| fmt: | ||||
| 	go fmt ./... | ||||
| 
 | ||||
| lint: | ||||
| 	golangci-lint run | ||||
| 	sh -c 'test -z "$$(gofmt -l .)"' | ||||
|  | ||||
							
								
								
									
										54
									
								
								bench.go
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								bench.go
									
									
									
									
									
								
							| @ -7,6 +7,7 @@ import ( | ||||
| 	"sort" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/schollz/progressbar/v3" | ||||
| 	"gonum.org/v1/gonum/stat" | ||||
| ) | ||||
| 
 | ||||
| @ -16,6 +17,7 @@ type TimingResult struct { | ||||
| 	Max        time.Duration | ||||
| 	Mean       time.Duration | ||||
| 	Median     time.Duration | ||||
| 	StdDev     time.Duration | ||||
| 	StartTime  time.Time | ||||
| 	EndTime    time.Time | ||||
| 	Duration   time.Duration | ||||
| @ -25,32 +27,64 @@ type TimingResult struct { | ||||
| // String returns a formatted string representation of the TimingResult.
 | ||||
| func (r TimingResult) String() string { | ||||
| 	return fmt.Sprintf( | ||||
| 		"Start Time: %v, End Time: %v, Duration: %v, Iterations: %d, Min: %v, Max: %v, Mean: %v, Median: %v", | ||||
| 		r.StartTime, r.EndTime, r.Duration, r.Iterations, r.Min, r.Max, r.Mean, r.Median, | ||||
| 		"Timing Results:\n"+ | ||||
| 			"Start Time: %v\n"+ | ||||
| 			"End Time: %v\n"+ | ||||
| 			"Total Duration: %v\n"+ | ||||
| 			"Iterations: %d\n"+ | ||||
| 			"Min Duration: %v\n"+ | ||||
| 			"Max Duration: %v\n"+ | ||||
| 			"Mean Duration: %v\n"+ | ||||
| 			"Median Duration: %v\n"+ | ||||
| 			"Standard Deviation: %v\n", | ||||
| 		r.StartTime.Format(time.RFC3339), | ||||
| 		r.EndTime.Format(time.RFC3339), | ||||
| 		r.Duration, | ||||
| 		r.Iterations, | ||||
| 		r.Min, | ||||
| 		r.Max, | ||||
| 		r.Mean, | ||||
| 		r.Median, | ||||
| 		r.StdDev, | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| // 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) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| @ -63,12 +97,14 @@ func TimeFunction(ctx context.Context, fn func() error, iterations int) (TimingR | ||||
| 	max := time.Duration(times[len(times)-1]) | ||||
| 	mean := time.Duration(stat.Mean(times, nil)) | ||||
| 	median := time.Duration(stat.Quantile(0.5, stat.Empirical, times, nil)) | ||||
| 	stdDev := time.Duration(stat.StdDev(times, nil)) | ||||
| 
 | ||||
| 	return TimingResult{ | ||||
| 		Min:        min, | ||||
| 		Max:        max, | ||||
| 		Mean:       mean, | ||||
| 		Median:     median, | ||||
| 		StdDev:     stdDev, | ||||
| 		StartTime:  startTime, | ||||
| 		EndTime:    endTime, | ||||
| 		Duration:   totalDuration, | ||||
|  | ||||
| @ -59,7 +59,6 @@ func quickSort(arr []int) { | ||||
| 
 | ||||
| 	for i := range arr { | ||||
| 		if arr[i] < arr[right] { | ||||
| 
 | ||||
| 			arr[i], arr[left] = arr[left], arr[i] | ||||
| 			left++ | ||||
| 		} | ||||
| @ -71,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) { | ||||
| @ -112,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) | ||||
| @ -127,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()) | ||||
| } | ||||
|  | ||||
							
								
								
									
										12
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								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 | ||||
| ) | ||||
|  | ||||
							
								
								
									
										25
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								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= | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user