Skip to content

Commit 8750df0

Browse files
committed
wip: add analysis mode impl
1 parent a82a2c4 commit 8750df0

6 files changed

Lines changed: 108 additions & 12 deletions

File tree

example/rle_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package example
2+
3+
import (
4+
"strconv"
5+
"strings"
6+
"testing"
7+
)
8+
9+
func rleBad(s string) string {
10+
if len(s) == 0 {
11+
return ""
12+
}
13+
var out string
14+
run := 1
15+
for i := 1; i <= len(s); i++ {
16+
if i < len(s) && s[i] == s[i-1] {
17+
run++
18+
continue
19+
}
20+
out += string(s[i-1])
21+
out += strconv.Itoa(run)
22+
out += "|"
23+
run = 1
24+
}
25+
return out
26+
}
27+
28+
func BenchmarkRLEBad(b *testing.B) {
29+
in := strings.Repeat("AAAABBBCCDAA", 200)
30+
b.ReportAllocs()
31+
for i := 0; i < b.N; i++ {
32+
_ = rleBad(in)
33+
}
34+
}
35+
36+
func leakyFunction() {
37+
s := make([]string, 3)
38+
for i := 0; i < 10000000; i++ {
39+
s = append(s, "magical pandas")
40+
}
41+
}
42+
43+
func BenchmarkLeakyFunction(b *testing.B) {
44+
for i := 0; i < b.N; i++ {
45+
leakyFunction()
46+
}
47+
}

go-runner/overlay/benchmark1.24.0.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ var labelsOnce sync.Once
284284
// subbenchmarks. b must not have subbenchmarks.
285285
func (b *B) run() {
286286
labelsOnce.Do(func() {
287-
fmt.Fprintf(b.w, "Running with CodSpeed (mode: walltime)\n")
287+
fmt.Fprintf(b.w, "Running with CodSpeed (mode: %s)\n", getCodspeedRunnerMode())
288288

289289
fmt.Fprintf(b.w, "goos: %s\n", runtime.GOOS)
290290
fmt.Fprintf(b.w, "goarch: %s\n", runtime.GOARCH)
@@ -347,8 +347,9 @@ func (b *B) launch() {
347347
// b.Loop does its own ramp-up logic so we just need to run it once.
348348
// If b.loop.n is non zero, it means b.Loop has already run.
349349
if b.loop.n == 0 {
350-
// Run the benchmark for at least the specified amount of time.
351-
if b.benchTime.n > 0 {
350+
if isAnalysisMode() {
351+
runBenchmarkSingle(b)
352+
} else if b.benchTime.n > 0 {
352353
// We already ran a single iteration in run1.
353354
// If -benchtime=1x was requested, use that result.
354355
// See https://golang.org/issue/32051.
@@ -421,7 +422,9 @@ func (b *B) loopSlowPath() bool {
421422

422423
if b.loop.n == 0 {
423424
// It's the first call to b.Loop() in the benchmark function.
424-
if b.benchTime.n > 0 {
425+
if isAnalysisMode() {
426+
b.loop.n = 1
427+
} else if b.benchTime.n > 0 {
425428
// Fixed iteration count.
426429
b.loop.n = uint64(b.benchTime.n)
427430
} else {
@@ -442,7 +445,9 @@ func (b *B) loopSlowPath() bool {
442445

443446
// Should we keep iterating?
444447
var more bool
445-
if b.benchTime.n > 0 {
448+
if isAnalysisMode() {
449+
more = false
450+
} else if b.benchTime.n > 0 {
446451
// The iteration count is fixed, so we should have run this many and now
447452
// be done.
448453
if b.loop.i != uint64(b.benchTime.n) {

go-runner/overlay/benchmark1.25.0.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ var labelsOnce sync.Once
284284
// subbenchmarks. b must not have subbenchmarks.
285285
func (b *B) run() {
286286
labelsOnce.Do(func() {
287-
fmt.Fprintf(b.w, "Running with CodSpeed (mode: walltime)\n")
287+
fmt.Fprintf(b.w, "Running with CodSpeed (mode: %s)\n", getCodspeedRunnerMode())
288288

289289
fmt.Fprintf(b.w, "goos: %s\n", runtime.GOOS)
290290
fmt.Fprintf(b.w, "goarch: %s\n", runtime.GOARCH)
@@ -347,8 +347,9 @@ func (b *B) launch() {
347347
// b.Loop does its own ramp-up logic so we just need to run it once.
348348
// If b.loop.n is non zero, it means b.Loop has already run.
349349
if b.loop.n == 0 {
350-
// Run the benchmark for at least the specified amount of time.
351-
if b.benchTime.n > 0 {
350+
if isAnalysisMode() {
351+
runBenchmarkSingle(b)
352+
} else if b.benchTime.n > 0 {
352353
// We already ran a single iteration in run1.
353354
// If -benchtime=1x was requested, use that result.
354355
// See https://golang.org/issue/32051.
@@ -421,7 +422,9 @@ func (b *B) loopSlowPath() bool {
421422

422423
if b.loop.n == 0 {
423424
// It's the first call to b.Loop() in the benchmark function.
424-
if b.benchTime.n > 0 {
425+
if isAnalysisMode() {
426+
b.loop.n = 1
427+
} else if b.benchTime.n > 0 {
425428
// Fixed iteration count.
426429
b.loop.n = uint64(b.benchTime.n)
427430
} else {
@@ -442,7 +445,9 @@ func (b *B) loopSlowPath() bool {
442445

443446
// Should we keep iterating?
444447
var more bool
445-
if b.benchTime.n > 0 {
448+
if isAnalysisMode() {
449+
more = false
450+
} else if b.benchTime.n > 0 {
446451
// The iteration count is fixed, so we should have run this many and now
447452
// be done.
448453
if b.loop.i != uint64(b.benchTime.n) {

go-runner/overlay/codspeed.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,28 @@ import (
1313
"time"
1414
)
1515

16+
type codspeedRunnerMode string
17+
18+
const (
19+
modeWalltime codspeedRunnerMode = "walltime"
20+
modeSimulation codspeedRunnerMode = "simulation"
21+
modeMemory codspeedRunnerMode = "memory"
22+
)
23+
24+
func getCodspeedRunnerMode() codspeedRunnerMode {
25+
v := strings.ToLower(strings.TrimSpace(os.Getenv("CODSPEED_RUNNER_MODE")))
26+
switch codspeedRunnerMode(v) {
27+
case modeSimulation, modeMemory:
28+
return codspeedRunnerMode(v)
29+
default:
30+
return modeWalltime
31+
}
32+
}
33+
34+
func isAnalysisMode() bool {
35+
return getCodspeedRunnerMode() != modeWalltime
36+
}
37+
1638
type codspeed struct {
1739
instrument_hooks *InstrumentHooks
1840

@@ -254,6 +276,9 @@ func (b *B) sendAccumulatedTimestamps() {
254276
}
255277

256278
func (b *B) SaveMeasurement() {
279+
if isAnalysisMode() {
280+
return
281+
}
257282
if b.savedMeasurement {
258283
return
259284
}
@@ -314,6 +339,13 @@ func (b *B) StartTimerWithoutMarker() {
314339
}
315340
}
316341

342+
func runBenchmarkSingle(b *B) {
343+
b.codspeed.instrument_hooks.StartBenchmark()
344+
b.runN(1)
345+
b.codspeed.instrument_hooks.StopBenchmark()
346+
b.sendAccumulatedTimestamps()
347+
}
348+
317349
func runBenchmarkWithWarmup(b *B) {
318350
warmupD := b.benchTime.d / 10
319351
warmupN := int64(1)

go-runner/src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@ pub fn run_benchmarks<P: AsRef<Path>>(
2525
bail!("Failed to run benchmarks: {error}");
2626
}
2727

28-
let profile_dir = profile_dir.as_ref().to_path_buf();
29-
collect_walltime_results(&profile_dir).unwrap();
28+
let mode = std::env::var("CODSPEED_RUNNER_MODE").unwrap_or_else(|_| "walltime".into());
29+
if mode == "walltime" {
30+
let profile_dir = profile_dir.as_ref().to_path_buf();
31+
collect_walltime_results(&profile_dir).unwrap();
32+
}
3033

3134
Ok(())
3235
}

go-runner/src/runner/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ fn run_cmd<P: AsRef<Path>>(
4444
cmd.env("GOCACHE", _dir.path().join("gocache"));
4545
cmd.env("GOMODCACHE", _dir.path().join("gomodcache"));
4646

47+
if let Ok(mode) = std::env::var("CODSPEED_RUNNER_MODE") {
48+
cmd.env("CODSPEED_RUNNER_MODE", mode);
49+
}
50+
4751
Ok((_dir, cmd))
4852
}
4953

0 commit comments

Comments
 (0)