Skip to content

Commit

Permalink
Add a perf compare tool
Browse files Browse the repository at this point in the history
Signed-off-by: Sergen Yalçın <[email protected]>
  • Loading branch information
sergenyalcin committed Oct 16, 2024
1 parent cf37a07 commit 188d75c
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 6 deletions.
6 changes: 3 additions & 3 deletions cmd/perf/internal/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ func (r Result) Print() {
log.Info(fmt.Sprintf("Peak %s: %f %s \n", r.Metric, r.Peak, r.MetricUnit))
}

func (r Result) PrintYaml(b *strings.Builder) {
func (r Result) PrintYaml(b *strings.Builder, yamlTag string) {

Check failure on line 115 in cmd/perf/internal/common/common.go

View workflow job for this annotation

GitHub Actions / lint

`b` can be `io.StringWriter` (interfacer)
if r.PodName != "" {
b.WriteString(fmt.Sprintf("Pod: %s\n", r.PodName))

Check failure on line 117 in cmd/perf/internal/common/common.go

View workflow job for this annotation

GitHub Actions / lint

preferFprint: suggestion: fmt.Fprintf(b, "Pod: %s\n", r.PodName) (gocritic)
}
b.WriteString(fmt.Sprintf("Average%s: %f\n", r.Metric, r.Average))
b.WriteString(fmt.Sprintf("Peak%s: %f\n", r.Metric, r.Peak))
b.WriteString(fmt.Sprintf("average_%s: %f\n", yamlTag, r.Average))

Check failure on line 119 in cmd/perf/internal/common/common.go

View workflow job for this annotation

GitHub Actions / lint

preferFprint: suggestion: fmt.Fprintf(b, "average_%s: %f\n", yamlTag, r.Average) (gocritic)
b.WriteString(fmt.Sprintf("peak_%s: %f\n", yamlTag, r.Peak))

Check failure on line 120 in cmd/perf/internal/common/common.go

View workflow job for this annotation

GitHub Actions / lint

preferFprint: suggestion: fmt.Fprintf(b, "peak_%s: %f\n", yamlTag, r.Peak) (gocritic)
}
6 changes: 3 additions & 3 deletions cmd/perf/internal/quantify.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,9 @@ func (o *QuantifyOptions) processPods(timeToReadinessResults []common.Result) er
if o.yamlOutput {
for _, timeToReadinessResult := range timeToReadinessResults {
b := strings.Builder{}
timeToReadinessResult.PrintYaml(&b)
aggregatedMemoryResult.PrintYaml(&b)
aggregatedCPURateResult.PrintYaml(&b)
timeToReadinessResult.PrintYaml(&b, "time_to_readiness")
aggregatedMemoryResult.PrintYaml(&b, "memory")
aggregatedCPURateResult.PrintYaml(&b, "cpu")

f, err := os.Create("results.yaml")
if err != nil {
Expand Down
87 changes: 87 additions & 0 deletions cmd/perfcompare/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package main

Check warning on line 1 in cmd/perfcompare/main.go

View workflow job for this annotation

GitHub Actions / lint

package-comments: should have a package comment (revive)

import (
"math"
"os"

log "github.com/sirupsen/logrus"
"gopkg.in/alecthomas/kingpin.v2"
"gopkg.in/yaml.v2"
)

type ApplicationPerformance struct {

Check warning on line 12 in cmd/perfcompare/main.go

View workflow job for this annotation

GitHub Actions / lint

exported: exported type ApplicationPerformance should have comment or be unexported (revive)
AverageTimeToReadiness float64 `yaml:"average_time_to_readiness"`
PeakTimeToReadiness float64 `yaml:"peak_time_to_readiness"`
AverageMemory float64 `yaml:"average_memory"`
PeakMemory float64 `yaml:"peak_memory"`
AverageCPU float64 `yaml:"average_cpu"`
PeakCPU float64 `yaml:"peak_cpu"`
}

// Compare two ApplicationPerformance structs and print the differences with a threshold check
func (ap ApplicationPerformance) Compare(newData ApplicationPerformance, threshold float64) {
log.Infoln("Comparing Performance:")
compareField("Average Time to Readiness", ap.AverageTimeToReadiness, newData.AverageTimeToReadiness, threshold)
compareField("Peak Time to Readiness", ap.PeakTimeToReadiness, newData.PeakTimeToReadiness, threshold)
compareField("Average Memory", ap.AverageMemory, newData.AverageMemory, threshold)
compareField("Peak Memory", ap.PeakMemory, newData.PeakMemory, threshold)
compareField("Average CPU", ap.AverageCPU, newData.AverageCPU, threshold)
compareField("Peak CPU", ap.PeakCPU, newData.PeakCPU, threshold)
}

func compareField(fieldName string, oldData, newData float64, threshold float64) {
diff := newData - oldData
percentChange := diff / oldData * 100
diff = math.Round(diff*100) / 100
percentChange = math.Round(percentChange*100) / 100

// Print the comparison result with 2 decimal places
log.Infof("%s: Old Data = %.2f, New Data = %.2f, Difference = %.2f (%.2f%% change)\n", fieldName, oldData, newData, diff, percentChange)

// Check if the percent change exceeds the threshold
if percentChange > threshold*100 {
log.Warnf("Attention: %s increased by more than %.0f%% -> %f\n", fieldName, threshold*100, percentChange)
}
}

// Read YAML file and unmarshal into ApplicationPerformance struct
func readYAMLFile(filename string) (ApplicationPerformance, error) {
data, err := os.ReadFile(filename)

Check failure on line 49 in cmd/perfcompare/main.go

View workflow job for this annotation

GitHub Actions / lint

G304: Potential file inclusion via variable (gosec)
if err != nil {
return ApplicationPerformance{}, err
}

var performance ApplicationPerformance
err = yaml.Unmarshal(data, &performance)
if err != nil {
return ApplicationPerformance{}, err
}

return performance, nil
}

func main() {
// Command-line argument parsing
app := kingpin.New("perf-compare", "A tool to compare application performance data from YAML files.")
old := app.Flag("old", "Path to the old results as YAML file.").Short('o').Required().String()
current := app.Flag("new", "Path to the new results as YAML file.").Short('n').Required().String()
threshold := app.Flag("threshold", "The threshold for the performance comparison like 0.10 for %10.").Short('t').Required().Float64()

if _, err := app.Parse(os.Args[1:]); err != nil {
log.Fatal(err)
}

// Read data from the YAML files
oldData, err := readYAMLFile(*old)
if err != nil {
log.Fatalf("Failed to read old data: %v", err)
}

newData, err := readYAMLFile(*current)
if err != nil {
log.Fatalf("Failed to read new data: %v", err)
}

// Compare the two datasets
oldData.Compare(newData, *threshold)
}
6 changes: 6 additions & 0 deletions cmd/perfcompare/testdata/newData.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
average_time_to_readiness: 5.800000
peak_time_to_readiness: 11.000000
average_memory: 33800000.00000
peak_memory: 44000000.000000
average_cpu: 65.000000
peak_cpu: 85.000000
6 changes: 6 additions & 0 deletions cmd/perfcompare/testdata/oldData.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
average_time_to_readiness: 5.000000
peak_time_to_readiness: 10.000000
average_memory: 33000000.00000
peak_memory: 40000000.000000
average_cpu: 60.000000
peak_cpu: 70.000000

0 comments on commit 188d75c

Please sign in to comment.