mirror of
https://github.com/ivuorinen/gibidify.git
synced 2026-01-26 11:34:03 +00:00
* chore(ci): update go to 1.25, add permissions and envs * fix(ci): update pr-lint.yml * chore: update go, fix linting * fix: tests and linting * fix(lint): lint fixes, renovate should now pass * fix: updates, security upgrades * chore: workflow updates, lint * fix: more lint, checkmake, and other fixes * fix: more lint, convert scripts to POSIX compliant * fix: simplify codeql workflow * tests: increase test coverage, fix found issues * fix(lint): editorconfig checking, add to linters * fix(lint): shellcheck, add to linters * fix(lint): apply cr comment suggestions * fix(ci): remove step-security/harden-runner * fix(lint): remove duplication, apply cr fixes * fix(ci): tests in CI/CD pipeline * chore(lint): deduplication of strings * fix(lint): apply cr comment suggestions * fix(ci): actionlint * fix(lint): apply cr comment suggestions * chore: lint, add deps management
186 lines
4.8 KiB
Go
186 lines
4.8 KiB
Go
// Package main provides a CLI for running gibidify benchmarks.
|
|
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"github.com/ivuorinen/gibidify/benchmark"
|
|
"github.com/ivuorinen/gibidify/gibidiutils"
|
|
)
|
|
|
|
var (
|
|
sourceDir = flag.String("source", "", "Source directory to benchmark (uses temp files if empty)")
|
|
benchmarkType = flag.String("type", "all", "Benchmark type: all, collection, processing, concurrency, format")
|
|
format = flag.String("format", "json", "Output format for processing benchmarks")
|
|
concurrency = flag.Int("concurrency", runtime.NumCPU(), "Concurrency level for processing benchmarks")
|
|
concurrencyList = flag.String("concurrency-list", "1,2,4,8", "Comma-separated list of concurrency levels")
|
|
formatList = flag.String("format-list", "json,yaml,markdown", "Comma-separated list of formats")
|
|
numFiles = flag.Int("files", 100, "Number of files to create for benchmarks")
|
|
)
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
if err := runBenchmarks(); err != nil {
|
|
_, _ = fmt.Fprintf(os.Stderr, "Benchmark failed: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func runBenchmarks() error {
|
|
fmt.Printf("Running gibidify benchmarks...\n")
|
|
fmt.Printf("Source: %s\n", getSourceDescription())
|
|
fmt.Printf("Type: %s\n", *benchmarkType)
|
|
fmt.Printf("CPU cores: %d\n", runtime.NumCPU())
|
|
fmt.Println()
|
|
|
|
switch *benchmarkType {
|
|
case "all":
|
|
return benchmark.RunAllBenchmarks(*sourceDir)
|
|
case "collection":
|
|
return runCollectionBenchmark()
|
|
case "processing":
|
|
return runProcessingBenchmark()
|
|
case "concurrency":
|
|
return runConcurrencyBenchmark()
|
|
case "format":
|
|
return runFormatBenchmark()
|
|
default:
|
|
return gibidiutils.NewValidationError(
|
|
gibidiutils.CodeValidationFormat,
|
|
"invalid benchmark type: "+*benchmarkType,
|
|
)
|
|
}
|
|
}
|
|
|
|
func runCollectionBenchmark() error {
|
|
fmt.Println("Running file collection benchmark...")
|
|
result, err := benchmark.FileCollectionBenchmark(*sourceDir, *numFiles)
|
|
if err != nil {
|
|
return gibidiutils.WrapError(
|
|
err,
|
|
gibidiutils.ErrorTypeProcessing,
|
|
gibidiutils.CodeProcessingCollection,
|
|
"file collection benchmark failed",
|
|
)
|
|
}
|
|
benchmark.PrintResult(result)
|
|
return nil
|
|
}
|
|
|
|
func runProcessingBenchmark() error {
|
|
fmt.Printf("Running file processing benchmark (format: %s, concurrency: %d)...\n", *format, *concurrency)
|
|
result, err := benchmark.FileProcessingBenchmark(*sourceDir, *format, *concurrency)
|
|
if err != nil {
|
|
return gibidiutils.WrapError(
|
|
err,
|
|
gibidiutils.ErrorTypeProcessing,
|
|
gibidiutils.CodeProcessingCollection,
|
|
"file processing benchmark failed",
|
|
)
|
|
}
|
|
benchmark.PrintResult(result)
|
|
return nil
|
|
}
|
|
|
|
func runConcurrencyBenchmark() error {
|
|
concurrencyLevels, err := parseConcurrencyList(*concurrencyList)
|
|
if err != nil {
|
|
return gibidiutils.WrapError(
|
|
err,
|
|
gibidiutils.ErrorTypeValidation,
|
|
gibidiutils.CodeValidationFormat,
|
|
"invalid concurrency list",
|
|
)
|
|
}
|
|
|
|
fmt.Printf("Running concurrency benchmark (format: %s, levels: %v)...\n", *format, concurrencyLevels)
|
|
suite, err := benchmark.ConcurrencyBenchmark(*sourceDir, *format, concurrencyLevels)
|
|
if err != nil {
|
|
return gibidiutils.WrapError(
|
|
err,
|
|
gibidiutils.ErrorTypeProcessing,
|
|
gibidiutils.CodeProcessingCollection,
|
|
"concurrency benchmark failed",
|
|
)
|
|
}
|
|
benchmark.PrintSuite(suite)
|
|
return nil
|
|
}
|
|
|
|
func runFormatBenchmark() error {
|
|
formats := parseFormatList(*formatList)
|
|
fmt.Printf("Running format benchmark (formats: %v)...\n", formats)
|
|
suite, err := benchmark.FormatBenchmark(*sourceDir, formats)
|
|
if err != nil {
|
|
return gibidiutils.WrapError(
|
|
err,
|
|
gibidiutils.ErrorTypeProcessing,
|
|
gibidiutils.CodeProcessingCollection,
|
|
"format benchmark failed",
|
|
)
|
|
}
|
|
benchmark.PrintSuite(suite)
|
|
return nil
|
|
}
|
|
|
|
func getSourceDescription() string {
|
|
if *sourceDir == "" {
|
|
return fmt.Sprintf("temporary files (%d files)", *numFiles)
|
|
}
|
|
return *sourceDir
|
|
}
|
|
|
|
func parseConcurrencyList(list string) ([]int, error) {
|
|
parts := strings.Split(list, ",")
|
|
levels := make([]int, 0, len(parts))
|
|
|
|
for _, part := range parts {
|
|
part = strings.TrimSpace(part)
|
|
var level int
|
|
if _, err := fmt.Sscanf(part, "%d", &level); err != nil {
|
|
return nil, gibidiutils.WrapErrorf(
|
|
err,
|
|
gibidiutils.ErrorTypeValidation,
|
|
gibidiutils.CodeValidationFormat,
|
|
"invalid concurrency level: %s",
|
|
part,
|
|
)
|
|
}
|
|
if level <= 0 {
|
|
return nil, gibidiutils.NewValidationError(
|
|
gibidiutils.CodeValidationFormat,
|
|
"concurrency level must be positive: "+part,
|
|
)
|
|
}
|
|
levels = append(levels, level)
|
|
}
|
|
|
|
if len(levels) == 0 {
|
|
return nil, gibidiutils.NewValidationError(
|
|
gibidiutils.CodeValidationFormat,
|
|
"no valid concurrency levels found",
|
|
)
|
|
}
|
|
|
|
return levels, nil
|
|
}
|
|
|
|
func parseFormatList(list string) []string {
|
|
parts := strings.Split(list, ",")
|
|
formats := make([]string, 0, len(parts))
|
|
|
|
for _, part := range parts {
|
|
part = strings.TrimSpace(part)
|
|
if part != "" {
|
|
formats = append(formats, part)
|
|
}
|
|
}
|
|
|
|
return formats
|
|
}
|