From d67b56cba6a4ada8fcb51f020ae796099d7f6406 Mon Sep 17 00:00:00 2001 From: Dima Koss Date: Sat, 27 Jan 2024 20:57:28 +0300 Subject: [PATCH] add perfgormance testing --- perf/Makefile | 2 + perf/README.md | 3 + perf/perf_test.go | 214 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 219 insertions(+) create mode 100644 perf/Makefile create mode 100644 perf/README.md create mode 100644 perf/perf_test.go diff --git a/perf/Makefile b/perf/Makefile new file mode 100644 index 0000000..8e49f96 --- /dev/null +++ b/perf/Makefile @@ -0,0 +1,2 @@ +all: + go test -bench=. diff --git a/perf/README.md b/perf/README.md new file mode 100644 index 0000000..3272fdb --- /dev/null +++ b/perf/README.md @@ -0,0 +1,3 @@ +# Performance testing + +All performance tests will be accumulated under the current directory diff --git a/perf/perf_test.go b/perf/perf_test.go new file mode 100644 index 0000000..75f99af --- /dev/null +++ b/perf/perf_test.go @@ -0,0 +1,214 @@ +package perf_test + +import ( + "runtime" + "testing" + + "github.com/koss-null/funcfrog/pkg/pipe" +) + +func fib(n int) int { + n = n % 91 + a, b := 0, 1 + for i := 0; i < n; i++ { + a, b = b, a+b + } + return a +} + +// Define the predicate function for the filter operation +func filterFunc(x *int) bool { + // Perform a complex condition check + return fib(*x%2) == 0 +} + +// Define the binary function for the reduce operation +func reduceFunc(x, y *int) int { + // Perform a complex calculation or aggregation + return fib(*x)%1024 + fib(*y)%1024 +} + +func BenchmarkMap(b *testing.B) { + b.StopTimer() + input := make([]int, 1_000_000) + for i := 0; i < len(input); i++ { + input[i] = i + } + b.StartTimer() + + for j := 0; j < b.N; j++ { + + // Create a Pipe from the input slice + pipe := pipe.Slice(input) + + // Apply the map operation to the Pipe + result := pipe.Map(fib).Do() + + // Perform any necessary assertions on the result + _ = result + } +} + +func BenchmarkMapParallel(b *testing.B) { + b.StopTimer() + input := make([]int, 1_000_000) + for i := 0; i < len(input); i++ { + input[i] = i + } + b.StartTimer() + + for j := 0; j < b.N; j++ { + + // Create a Pipe from the input slice + pipe := pipe.Slice(input).Parallel(uint16(runtime.NumCPU())) + + // Apply the map operation to the Pipe + result := pipe.Map(fib).Do() + + // Perform any necessary assertions on the result + _ = result + } +} + +func BenchmarkMapFor(b *testing.B) { + b.StopTimer() + input := make([]int, 1_000_000) + for i := 0; i < len(input); i++ { + input[i] = i + } + b.StartTimer() + + for j := 0; j < b.N; j++ { + + result := make([]int, 0, len(input)) + for i := range input { + result = append(result, fib(input[i])) + } + + // Perform any necessary assertions on the result + _ = result + } +} + +func BenchmarkFilter(b *testing.B) { + b.StopTimer() + input := make([]int, 1_000_000) + for i := 0; i < len(input); i++ { + input[i] = i + } + b.StartTimer() + + for j := 0; j < b.N; j++ { + // Create a Pipe from the input slice + pipe := pipe.Slice(input) + + // Apply the filter operation to the Pipe + result := pipe.Filter(filterFunc).Do() + + // Perform any necessary assertions on the result + _ = result + } +} + +func BenchmarkFilterParallel(b *testing.B) { + b.StopTimer() + input := make([]int, 1_000_000) + for i := 0; i < len(input); i++ { + input[i] = i + } + b.StartTimer() + + for j := 0; j < b.N; j++ { + // Create a Pipe from the input slice + pipe := pipe.Slice(input).Parallel(uint16(runtime.NumCPU())) + + // Apply the filter operation to the Pipe + result := pipe.Filter(filterFunc).Do() + + // Perform any necessary assertions on the result + _ = result + } +} + +func BenchmarkFilterFor(b *testing.B) { + b.StopTimer() + input := make([]int, 1_000_000) + for i := 0; i < len(input); i++ { + input[i] = i + } + b.StartTimer() + + for j := 0; j < b.N; j++ { + + // Apply the filter operation to the Pipe + result := make([]int, 0) + for i := range input { + if filterFunc(&input[i]) { + result = append(result, input[i]) + } + } + + // Perform any necessary assertions on the result + _ = result + } +} + +func BenchmarkReduce(b *testing.B) { + b.StopTimer() + input := make([]int, 1_000_000) + for i := 0; i < len(input); i++ { + input[i] = i + } + b.StartTimer() + + for j := 0; j < b.N; j++ { + pipe := pipe.Slice(input) + + // Apply the reduce operation to the Pipe + result := pipe.Reduce(reduceFunc) + + // Perform any necessary assertions on the result + _ = result + } +} + +func BenchmarkSumParallel(b *testing.B) { + b.StopTimer() + input := make([]int, 1_000_000) + for i := 0; i < len(input); i++ { + input[i] = i + } + b.StartTimer() + + for j := 0; j < b.N; j++ { + // Create a Pipe from the input slice + pipe := pipe.Slice(input).Parallel(uint16(runtime.NumCPU())) + + // Apply the reduce operation to the Pipe + result := pipe.Sum(reduceFunc) + + // Perform any necessary assertions on the result + _ = result + } +} + +// Benchmark the reduce with for-loop +func BenchmarkReduceFor(b *testing.B) { + b.StopTimer() + input := make([]int, 1_000_000) + for i := 0; i < len(input); i++ { + input[i] = i + } + b.StartTimer() + + for j := 0; j < b.N; j++ { + // Apply the reduce operation to the Pipe + result := 0 + for i := range input { + result = reduceFunc(&result, &input[i]) + } + + // Perform any necessary assertions on the result + _ = result + } +}