Compare commits
No commits in common. "fb13c5c56a02c6cd16757f9d8d5a0fd0d1b5e169" and "81b25d1421a9549012b50632056863ba6adcd842" have entirely different histories.
fb13c5c56a
...
81b25d1421
7
Makefile
7
Makefile
@ -2,10 +2,3 @@ default: test
|
|||||||
|
|
||||||
test:
|
test:
|
||||||
go test -v -count=1 ./...
|
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,7 +7,6 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/schollz/progressbar/v3"
|
|
||||||
"gonum.org/v1/gonum/stat"
|
"gonum.org/v1/gonum/stat"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -17,7 +16,6 @@ type TimingResult struct {
|
|||||||
Max time.Duration
|
Max time.Duration
|
||||||
Mean time.Duration
|
Mean time.Duration
|
||||||
Median time.Duration
|
Median time.Duration
|
||||||
StdDev time.Duration
|
|
||||||
StartTime time.Time
|
StartTime time.Time
|
||||||
EndTime time.Time
|
EndTime time.Time
|
||||||
Duration time.Duration
|
Duration time.Duration
|
||||||
@ -27,64 +25,32 @@ type TimingResult struct {
|
|||||||
// String returns a formatted string representation of the TimingResult.
|
// String returns a formatted string representation of the TimingResult.
|
||||||
func (r TimingResult) String() string {
|
func (r TimingResult) String() string {
|
||||||
return fmt.Sprintf(
|
return fmt.Sprintf(
|
||||||
"Timing Results:\n"+
|
"Start Time: %v, End Time: %v, Duration: %v, Iterations: %d, Min: %v, Max: %v, Mean: %v, Median: %v",
|
||||||
"Start Time: %v\n"+
|
r.StartTime, r.EndTime, r.Duration, r.Iterations, r.Min, r.Max, r.Mean, r.Median,
|
||||||
"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
|
// TimeFunction runs the given function fn a specified number of times and returns the timing results.
|
||||||
// and returns the timing results. It supports context for cancellation.
|
// It supports context for cancellation.
|
||||||
func TimeFunction(
|
func TimeFunction(ctx context.Context, fn func() error, iterations int) (TimingResult, error) {
|
||||||
ctx context.Context,
|
|
||||||
fn func(),
|
|
||||||
iterations int,
|
|
||||||
) (TimingResult, error) {
|
|
||||||
if iterations <= 0 {
|
if iterations <= 0 {
|
||||||
return TimingResult{}, errors.New(
|
return TimingResult{}, errors.New("iterations must be greater than 0")
|
||||||
"iterations must be greater than 0")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
times := make([]float64, 0, iterations)
|
times := make([]float64, 0, iterations)
|
||||||
startTime := time.Now().UTC()
|
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++ {
|
for i := 0; i < iterations; i++ {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return TimingResult{}, ctx.Err()
|
return TimingResult{}, ctx.Err()
|
||||||
default:
|
default:
|
||||||
iterStart := time.Now().UTC()
|
iterStart := time.Now().UTC()
|
||||||
fn()
|
if err := fn(); err != nil {
|
||||||
|
return TimingResult{}, err
|
||||||
|
}
|
||||||
elapsed := time.Since(iterStart)
|
elapsed := time.Since(iterStart)
|
||||||
times = append(times, float64(elapsed))
|
times = append(times, float64(elapsed))
|
||||||
|
|
||||||
bar.Add(1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,14 +63,12 @@ func TimeFunction(
|
|||||||
max := time.Duration(times[len(times)-1])
|
max := time.Duration(times[len(times)-1])
|
||||||
mean := time.Duration(stat.Mean(times, nil))
|
mean := time.Duration(stat.Mean(times, nil))
|
||||||
median := time.Duration(stat.Quantile(0.5, stat.Empirical, times, nil))
|
median := time.Duration(stat.Quantile(0.5, stat.Empirical, times, nil))
|
||||||
stdDev := time.Duration(stat.StdDev(times, nil))
|
|
||||||
|
|
||||||
return TimingResult{
|
return TimingResult{
|
||||||
Min: min,
|
Min: min,
|
||||||
Max: max,
|
Max: max,
|
||||||
Mean: mean,
|
Mean: mean,
|
||||||
Median: median,
|
Median: median,
|
||||||
StdDev: stdDev,
|
|
||||||
StartTime: startTime,
|
StartTime: startTime,
|
||||||
EndTime: endTime,
|
EndTime: endTime,
|
||||||
Duration: totalDuration,
|
Duration: totalDuration,
|
||||||
|
@ -59,6 +59,7 @@ func quickSort(arr []int) {
|
|||||||
|
|
||||||
for i := range arr {
|
for i := range arr {
|
||||||
if arr[i] < arr[right] {
|
if arr[i] < arr[right] {
|
||||||
|
|
||||||
arr[i], arr[left] = arr[left], arr[i]
|
arr[i], arr[left] = arr[left], arr[i]
|
||||||
left++
|
left++
|
||||||
}
|
}
|
||||||
@ -70,12 +71,40 @@ func quickSort(arr []int) {
|
|||||||
quickSort(arr[left+1:])
|
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.
|
// sampleFunction performs a mix of different operations to introduce variability in runtime.
|
||||||
func sampleFunction() {
|
func sampleFunction() error {
|
||||||
randomSleep()
|
randomSleep()
|
||||||
generatePrimes(500 + rand.Intn(1500))
|
generatePrimes(500 + rand.Intn(1500))
|
||||||
sortRandomSlice(500 + rand.Intn(1500))
|
sortRandomSlice(500 + rand.Intn(1500))
|
||||||
multiplyMatrices(20 + rand.Intn(10))
|
multiplyMatrices(20 + rand.Intn(10))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimeFunction(t *testing.T) {
|
func TestTimeFunction(t *testing.T) {
|
||||||
@ -83,7 +112,7 @@ func TestTimeFunction(t *testing.T) {
|
|||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
|
||||||
// Define the number of iterations.
|
// Define the number of iterations.
|
||||||
iterations := 700
|
iterations := 1000
|
||||||
|
|
||||||
// Create a context with a timeout for cancellation.
|
// Create a context with a timeout for cancellation.
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||||
@ -98,58 +127,3 @@ func TestTimeFunction(t *testing.T) {
|
|||||||
// Print the timing results.
|
// Print the timing results.
|
||||||
t.Logf(result.String())
|
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,14 +2,4 @@ module git.eeqj.de/sneak/timingbench
|
|||||||
|
|
||||||
go 1.22.2
|
go 1.22.2
|
||||||
|
|
||||||
require (
|
require gonum.org/v1/gonum v0.15.0 // indirect
|
||||||
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,27 +1,2 @@
|
|||||||
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 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ=
|
||||||
gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo=
|
gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo=
|
||||||
|
Loading…
Reference in New Issue
Block a user