package timingbench import ( "context" "math/rand" "testing" "time" ) // isPrime checks if a number is a prime number. func isPrime(n int) bool { if n <= 1 { return false } for i := 2; i*i <= n; i++ { if n%i == 0 { return false } } return true } // randomSleep introduces a random delay between 1 and 20 milliseconds. func randomSleep() { time.Sleep(time.Duration(rand.Intn(20)+1) * time.Millisecond) } // generatePrimes generates prime numbers up to a given limit. func generatePrimes(limit int) []int { primes := []int{} for i := 2; i <= limit; i++ { if isPrime(i) { primes = append(primes, i) } } return primes } // sortRandomSlice generates a slice with random integers and sorts it. func sortRandomSlice(size int) { slice := make([]int, size) for i := range slice { slice[i] = rand.Intn(10000) } quickSort(slice) } // quickSort sorts a slice of integers using the quicksort algorithm. func quickSort(arr []int) { if len(arr) < 2 { return } left, right := 0, len(arr)-1 pivotIndex := rand.Int() % len(arr) arr[pivotIndex], arr[right] = arr[right], arr[pivotIndex] for i := range arr { if arr[i] < arr[right] { arr[i], arr[left] = arr[left], arr[i] left++ } } arr[left], arr[right] = arr[right], arr[left] quickSort(arr[:left]) quickSort(arr[left+1:]) } // sampleFunction performs a mix of different operations to introduce variability in runtime. func sampleFunction() { randomSleep() generatePrimes(500 + rand.Intn(1500)) sortRandomSlice(500 + rand.Intn(1500)) multiplyMatrices(20 + rand.Intn(10)) } func TestTimeFunction(t *testing.T) { // Define the number of iterations. iterations := 700 // Create a context with a timeout for cancellation. ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) defer cancel() // Measure the execution times of the sample function. result, err := TimeFunction(ctx, sampleFunction, iterations) if err != nil { t.Fatalf("Error measuring function: %v", err) } // 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()) }