package benchmark
|
|
import (
|
"reflect"
|
"testing"
|
|
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson/bsontype"
|
)
|
|
func reflection(documents interface{}) {
|
dv := reflect.ValueOf(documents)
|
if dv.Kind() != reflect.Slice {
|
return
|
}
|
|
if dv.Len() == 0 {
|
return
|
}
|
|
docSlice := make([]interface{}, 0, dv.Len())
|
for i := 0; i < dv.Len(); i++ {
|
docSlice = append(docSlice, dv.Index(i).Interface())
|
}
|
}
|
|
func _switch(documents interface{}) {
|
bytes, err := bson.Marshal(struct {
|
Arr any `bson:"arr"`
|
}{Arr: documents})
|
if err != nil {
|
panic(err)
|
}
|
|
raw := bson.Raw(bytes).Lookup("arr")
|
|
var docSlice []bson.Raw
|
switch raw.Type {
|
case bsontype.Array:
|
elems, err := raw.Array().Elements()
|
if err != nil {
|
panic(err)
|
}
|
|
docSlice = make([]bson.Raw, len(elems))
|
for idx, elem := range elems {
|
docSlice[idx] = elem.Value().Document()
|
}
|
}
|
|
if len(docSlice) == 0 {
|
panic(2)
|
}
|
}
|
|
type Document struct {
|
A, B string
|
}
|
|
func TestSwitch(t *testing.T) {
|
docs := []Document{{A: "A", B: "B"}}
|
_switch(docs)
|
}
|
|
func BenchmarkReflection(b *testing.B) {
|
// Prepare a sample input for the reflection function
|
var data []Document
|
for i := 0; i < 1000; i++ {
|
data = append(data, Document{A: "A", B: "B"})
|
}
|
|
b.ReportAllocs()
|
b.ResetTimer()
|
for i := 0; i < b.N; i++ {
|
reflection(data)
|
}
|
}
|
|
func BenchmarkSwitch(b *testing.B) {
|
// Prepare a sample input for the _switch function
|
var data []interface{}
|
for i := 0; i < 1000; i++ {
|
data = append(data, Document{A: "A"})
|
}
|
|
b.ReportAllocs()
|
b.ResetTimer()
|
for i := 0; i < b.N; i++ {
|
_switch(data)
|
}
|
}
|