Skip to content

Instantly share code, notes, and snippets.

@yosiat
Created October 5, 2022 10:02
Show Gist options
  • Save yosiat/930426f4baea92b5f188203c6acb716b to your computer and use it in GitHub Desktop.
Save yosiat/930426f4baea92b5f188203c6acb716b to your computer and use it in GitHub Desktop.
package quamina
import (
"fmt"
"io"
"os"
"testing"
)
var (
topCount int
event []byte
)
type quotesCounter struct {
event []byte // event being processed, treated as immutable
eventIndex int // current byte index into the event
length int
}
func (qc *quotesCounter) countQuotesWithStepping(event []byte) int {
qc.eventIndex = 0
qc.event = event
qc.length = len(qc.event)
count := 0
for {
ch := qc.ch()
if ch == '"' {
count++
}
if qc.step() != nil {
return count
}
}
}
func (qc *quotesCounter) countQuotesWithFor(event []byte) int {
qc.eventIndex = 0
qc.event = event
count := 0
index := 0
for index < len(qc.event) {
ch := qc.event[index]
if ch == '"' {
count++
}
index++
}
return count
}
// ch fetches the next byte from the event. It doesn't check array bounds,
// so it's the caller's responsibility to ensure we haven't run off the end of the event.
func (qc *quotesCounter) ch() byte {
return qc.event[qc.eventIndex]
}
// step advances the event pointer and returns an error if you've run off the end of the event
func (qc *quotesCounter) step() error {
qc.eventIndex++
if qc.eventIndex >= qc.length {
// In real qumina we return good error, since we are reading till end of input
// we can return EOF, which is more efficient than doing `fmt.Errorf`
return io.EOF
}
return nil
}
func init() {
var err error
event, err = os.ReadFile("./testdata/status.json")
if err != nil {
panic(fmt.Sprintf("Failed to read file: %s", err))
}
}
func Benchmark_QuotesCount_Stepping(b *testing.B) {
var localCount int
counter := &quotesCounter{}
count := counter.countQuotesWithStepping(event)
b.Logf("Quotes count: %d", count)
b.ResetTimer()
for i := 0; i < b.N; i++ {
count := counter.countQuotesWithStepping(event)
localCount = count
}
topCount = localCount
}
func Benchmark_QuotesCount_For(b *testing.B) {
var localCount int
counter := &quotesCounter{}
count := counter.countQuotesWithFor(event)
b.Logf("Quotes count: %d", count)
b.ResetTimer()
for i := 0; i < b.N; i++ {
count := counter.countQuotesWithFor(event)
localCount = count
}
topCount = localCount
}
 ❯ go test  -benchmem -run="^$" -bench "^Benchmark_Quotes" 
goos: darwin
goarch: arm64
pkg: github.com/timbray/quamina
Benchmark_QuotesCount_Stepping-10    	   57076	     19373 ns/op	       0 B/op	       0 allocs/op
--- BENCH: Benchmark_QuotesCount_Stepping-10
    counting_quotes_bench_test.go:93: Quotes count: 642
    counting_quotes_bench_test.go:93: Quotes count: 642
    counting_quotes_bench_test.go:93: Quotes count: 642
    counting_quotes_bench_test.go:93: Quotes count: 642
Benchmark_QuotesCount_For-10         	  393404	      2998 ns/op	       0 B/op	       0 allocs/op
--- BENCH: Benchmark_QuotesCount_For-10
    counting_quotes_bench_test.go:110: Quotes count: 642
    counting_quotes_bench_test.go:110: Quotes count: 642
    counting_quotes_bench_test.go:110: Quotes count: 642
    counting_quotes_bench_test.go:110: Quotes count: 642
PASS
ok  	github.com/timbray/quamina	2.763s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment