Skip to content

Commit

Permalink
fix(benchmark): fix unintentional b.Fail(), refactor benchmark (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
muktihari authored Aug 3, 2023
1 parent 096466a commit 044b386
Showing 1 changed file with 103 additions and 52 deletions.
155 changes: 103 additions & 52 deletions expr_benchmark_test.go
Original file line number Diff line number Diff line change
@@ -1,90 +1,141 @@
package expr_test

import (
"fmt"
"math"
"testing"

"github.com/muktihari/expr"
)

func BenchmarkInt(b *testing.B) {
intExpr := "((2 + 2) * 4 / 4) * 10 + 4 * (50 + 50)"
multiply := func(s string, n int) (string, int) {
eq := 440
for i := 1; i < n; i++ {
s = s + " + (" + s + ")"
eq += eq
}
return s, eq
var exprs = [...]string{
expr.KindBoolean: "((3 + 2 == 5) && (7 * 2 <= 10)) || (!(4 + 1 == 5) && (2 / 1 < 5)) || ((8 >= 10) && (!(6 + 3 > 9))) || (9 % 4 == 1)", // true
expr.KindInt: "((10 + 2 * 5) / (7 - 3)) + ((15 - 2 * 3) * 2)", // int64: 23
expr.KindFloat: "(((12 + 5) * (7 - 3)) / (2 + 1) + (6 * (4 - 2)) - 5) * 2 + (8 / 2.2)", // float64: 62.9696969697
expr.KindImag: "((3 + 2i) * (2 - 4i)) / ((1 + 3i) + (2i - 1))", // complex128: (-1.6-2.8i)
}

func BenchmarkAny(b *testing.B) {
results := [...]interface{}{
expr.KindBoolean: true,
expr.KindInt: int64(23),
expr.KindFloat: float64(62.9696969697),
expr.KindImag: complex(-1.6, -2.8),
}

for n := 1; n <= 16; n *= 2 {
s, eq := multiply(intExpr, n)
b.Run(fmt.Sprintf("%d [^%d]", len(s), n), func(b *testing.B) {
for i, e := range exprs {
i, e := i, e
kind := expr.Kind(i)
if e == "" {
continue
}

b.Run(kind.String(), func(b *testing.B) {
for i := 0; i < b.N; i++ {
v, err := expr.Int(s)
v, err := expr.Any(e)
if err != nil {
b.Fatalf("expected nil, got: %v", err)
}
if v != eq {
b.Fatalf("expected %d, got: %d", eq, v)

// handle float prec
vf, vok := v.(float64)
rf, rok := results[kind].(float64)
if vok && rok {
digit := 1e10
v := math.Round(vf*digit) / digit
r := math.Round(rf*digit) / digit
if v != r {
b.Fatalf("expected value %v, got: %v", r, v)
}
continue
}

if v != results[kind] {
b.Fatalf("expected value %v, got: %v", results[kind], v)
}
}
})
}
}

func BenchmarkFloat64(b *testing.B) {
floatExpr := "((2 + 2) * 4 / 4) * 10.7 + 4.234567 * (50 + 50)"
multiply := func(s string, n int) (string, float64) {
eq := 466.2567
for i := 1; i < n; i++ {
s = s + " + (" + s + ")"
eq += eq
func BenchmarkBoolean(b *testing.B) {
for i, e := range exprs {
i, e := i, e
kind := expr.Kind(i)
if kind != expr.KindBoolean {
continue
}
return s, eq
}

for n := 1; n <= 16; n *= 2 {
s, eq := multiply(floatExpr, n)
b.Run(fmt.Sprintf("%d [^%d]", len(s), n), func(b *testing.B) {
b.Run(kind.String(), func(b *testing.B) {
for i := 0; i < b.N; i++ {
v, err := expr.Float64(s)
v, err := expr.Bool(e)
if err != nil {
b.Fatalf("expected nil, got: %v", err)
}
if v != eq {
b.Fatalf("expected %f, got: %f", eq, v)
if v != true {
b.Fatalf("expected %t, got: %t", true, v)
}
}
})
}
}

b.Fail()
func BenchmarkComplex128(b *testing.B) {
var (
e string = exprs[expr.KindImag]
r complex128 = complex(-1.6, -2.8)
)

b.Run(expr.KindImag.String(), func(b *testing.B) {
for i := 0; i < b.N; i++ {
v, err := expr.Complex128(e)
if err != nil {
b.Fatalf("expected nil, got: %v", err)
}
if v != r {
b.Fatalf("expected value: %f, got: %f", r, v)
}
}
})
}

func BenchmarkBoolean(b *testing.B) {
booleanExpr := "(\"expr\" == \"expr\" && \"Expr\" == \"expr\") || !false && 1 < 2 && (1 > 2 || -1 > -2)"
multiply := func(s string, n int) string {
for i := 1; i < n; i++ {
s += " && (" + s + ")"
func BenchmarkFloat64(b *testing.B) {
var (
e string = exprs[expr.KindFloat]
r float64 = 62.9696969697
)

b.Run(expr.KindFloat.String(), func(b *testing.B) {
for i := 0; i < b.N; i++ {
v, err := expr.Float64(e)
if err != nil {
b.Fatalf("expected nil, got: %v", err)
}
// handle float prec
digit := 1e10
v = math.Round(v*digit) / digit
r = math.Round(r*digit) / digit
if v != r {
b.Fatalf("expected value: %f, got: %f", r, v)
}
}
return s
}
})
}

for n := 1; n <= 16; n *= 2 {
s := multiply(booleanExpr, n)
b.Run(fmt.Sprintf("%d [^%d]", len(s), n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
v, err := expr.Bool(s)
if err != nil {
b.Fatalf("expected nil, got: %v", err)
}
func BenchmarkInt64(b *testing.B) {
var (
e string = exprs[expr.KindInt]
r int64 = 23
)

if v != true {
b.Fatalf("expected nil, got: %v", v)
}
b.Run(expr.KindInt.String(), func(b *testing.B) {
for i := 0; i < b.N; i++ {
v, err := expr.Int64(e)
if err != nil {
b.Fatalf("expected nil, got: %v", err)
}
})
}
if v != r {
b.Fatalf("expected value: %d, got: %d", r, v)
}
}
})
}

0 comments on commit 044b386

Please sign in to comment.