Skip to content

Commit

Permalink
feat: initiate benchmarking with filter function
Browse files Browse the repository at this point in the history
  • Loading branch information
farbodahm committed Mar 30, 2024
1 parent ede23c3 commit d94f6ec
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 0 deletions.
68 changes: 68 additions & 0 deletions benchmarks/filter_benchmark_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package benchmarks

import (
"context"
"testing"

"github.com/farbodahm/streame/pkg/core"
"github.com/farbodahm/streame/pkg/functions"
"github.com/farbodahm/streame/pkg/types"
"github.com/farbodahm/streame/pkg/utils"
)

// heavy_filter_stages creates a heavy struct with lots of
// fields and filter stages to take benchmark
func heavy_filter_stages(number_of_stages int, number_of_records int) {
input := make(chan types.Record)
output := make(chan types.Record)
errors := make(chan error)

sdf := core.StreamDataFrame{
SourceStream: input,
OutputStream: output,
ErrorStream: errors,
Stages: []core.Stage{},
}

// Create stages
filter := functions.Filter{
ColumnName: "Field1",
Value: "foobar",
Operator: functions.NOT_EQUAL,
}
result_df := sdf.Filter(filter)
for i := 0; i < number_of_stages; i++ {
result_df = result_df.Filter(filter)
}

// Generate sample data
heavy_struct := utils.NewHeavyStruct(40)
heavy_map, err := utils.ConvertStructToMap(heavy_struct)
if err != nil {
panic(err)
}
heavy_record := types.Record{
Key: "key1",
Value: heavy_map,
}

go func() {
for i := 0; i < number_of_records; i++ {
input <- heavy_record
}
}()

ctx, cancel := context.WithCancel(context.Background())
result_df.Execute(ctx)

for i := 0; i < number_of_records; i++ {
<-output
}
cancel()
}

func BenchmarkFilterFunction(b *testing.B) {
for i := 0; i < b.N; i++ {
heavy_filter_stages(100, 1000)
}
}
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ require (
)

require (
github.com/chzyer/readline v1.5.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/google/pprof v0.0.0-20240327155427-868f304927ed // indirect
github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.18.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
11 changes: 11 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ github.com/Microsoft/hcsshim v0.9.4 h1:mnUj0ivWy6UzbB1uLFqKR6F+ZyiDc7j4iGgHTpO+5
github.com/Microsoft/hcsshim v0.9.4/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/confluentinc/confluent-kafka-go/v2 v2.3.0 h1:icCHutJouWlQREayFwCc7lxDAhws08td+W3/gdqgZts=
github.com/confluentinc/confluent-kafka-go/v2 v2.3.0/go.mod h1:/VTy8iEpe6mD9pkCH5BhijlUl8ulUXymKv1Qig5Rgb8=
github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA=
Expand All @@ -29,8 +33,12 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/pprof v0.0.0-20240327155427-868f304927ed h1:n8QtJTrwsv3P7dNxPaMeNkMcxvUpqocsHLr8iDLGlQI=
github.com/google/pprof v0.0.0-20240327155427-868f304927ed/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465 h1:KwWnWVWCNtNq/ewIX7HIKnELmEx2nDP42yskD/pi7QE=
github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/moby/sys/mount v0.3.3 h1:fX1SVkXFJ47XWDoeFW4Sq7PdQJnV2QIDZAqjNqgEjUs=
Expand Down Expand Up @@ -66,8 +74,11 @@ go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633 h1:0BOZf6qNozI3pkN3fJLwNubheHJYHhMh91GRFOWWK08=
google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=
google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag=
Expand Down
113 changes: 113 additions & 0 deletions pkg/utils/test_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package utils

import (
"fmt"
"math/rand"
"reflect"
"strconv"
"time"
)

// HeavyStruct is a heavy object to be used for benchmarking tests.
type HeavyStruct struct {
Field1 string
Field2 string
Field3 string
Field4 string
Field5 string
Field6 string
Field7 string
Field8 string
Field9 string
Field10 string
Field11 string
Field12 string
Field13 string
Field14 string
Field15 string
Field16 string
Field17 string
Field18 string
Field19 string
Field20 string
}

// GenerateRandomString generates a random string of the specified length.
func GenerateRandomString(length int) string {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var seededRand *rand.Rand = rand.New(rand.NewSource(time.Now().UnixNano()))

b := make([]byte, length)
for i := range b {
b[i] = charset[seededRand.Intn(len(charset))]
}
return string(b)
}

// NewHeavyStruct creates a new HeavyStruct with random string values
// with given length.
func NewHeavyStruct(string_length int) HeavyStruct {
return HeavyStruct{
Field1: GenerateRandomString(string_length),
Field2: GenerateRandomString(string_length),
Field3: GenerateRandomString(string_length),
Field4: GenerateRandomString(string_length),
Field5: GenerateRandomString(string_length),
Field6: GenerateRandomString(string_length),
Field7: GenerateRandomString(string_length),
Field8: GenerateRandomString(string_length),
Field9: GenerateRandomString(string_length),
Field10: GenerateRandomString(string_length),
Field11: GenerateRandomString(string_length),
Field12: GenerateRandomString(string_length),
Field13: GenerateRandomString(string_length),
Field14: GenerateRandomString(string_length),
Field15: GenerateRandomString(string_length),
Field16: GenerateRandomString(string_length),
Field17: GenerateRandomString(string_length),
Field18: GenerateRandomString(string_length),
Field19: GenerateRandomString(string_length),
Field20: GenerateRandomString(string_length),
}
}

// TODO: After adding schema support to SDF, we shouldn't need this function.
// ConvertStructToMap converts a struct to a map[string]string.
// It uses reflection to iterate over the struct's fields.
// Note: This function does not handle nested structs or pointer fields.
func ConvertStructToMap(s interface{}) (map[string]string, error) {
v := reflect.ValueOf(s)
if v.Kind() != reflect.Struct {
return nil, fmt.Errorf("expected struct, got %s", v.Kind())
}

t := v.Type()
result := make(map[string]string)

for i := 0; i < v.NumField(); i++ {
field := v.Field(i)
fieldName := t.Field(i).Name

// Convert each field to string in a basic way.
// You might want to customize this part based on your needs.
var valueStr string
switch field.Kind() {
case reflect.String:
valueStr = field.String()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
valueStr = strconv.FormatInt(field.Int(), 10)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
valueStr = strconv.FormatUint(field.Uint(), 10)
case reflect.Float32, reflect.Float64:
valueStr = strconv.FormatFloat(field.Float(), 'f', -1, 64)
case reflect.Bool:
valueStr = strconv.FormatBool(field.Bool())
default:
return nil, fmt.Errorf("field %s has unsupported type %s", fieldName, field.Kind())
}

result[fieldName] = valueStr
}

return result, nil
}

0 comments on commit d94f6ec

Please sign in to comment.