package bench import ( "context" "fmt" "go_dreamfactory/lego/core" "go_dreamfactory/lego/sys/mgo" "go_dreamfactory/sys/db" "log" "os" reflect "reflect" "testing" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) var mdb *db.DB // func TestMain(m *testing.M) { // imgo, err := mgo.NewSys(mgo.SetMongodbUrl("mongodb://admin:123456@10.0.0.9:27018"), mgo.SetMongodbDatabase("dreamfactory")) // if err != nil { // log.Fatal(err) // } // mdb = &db.DB{} // mdb.SetMgo(imgo) // defer os.Exit(m.Run()) // } var mgoDb *mongo.Database func TestMain(m *testing.M) { option := options.Client().ApplyURI("mongodb://admin:123456@10.0.0.9:27018") client, err := mongo.Connect(context.TODO(), option) if err != nil { log.Fatal(err) } log.Print("connect mongo success") mgoDb = client.Database("dreamfactory") // imgo, err := mgo.NewSys(mgo.SetMongodbUrl("mongodb://admin:123456@10.0.0.9:27018"), mgo.SetMongodbDatabase("dreamfactory")) if err != nil { log.Fatal(err) } mdb = &db.DB{} mdb.SetMgo(imgo) defer os.Exit(m.Run()) } func BenchmarkMarsh(b *testing.B) { var ( // ncpu = runtime.NumCPU() parallelisms = []int{2} //平行数 dataSizes = []int{10, 100, 1000} //测试次数 builders = []TargetBuilder{ { Name: "gen", Make: func(bench Benchmark) (Target, error) { return Target{ GetHeroList: func() (any, error) { // heroes := GetList3(new(DBHero)) heroes := []*DBHero{} GetList(&heroes) return heroes, nil }, }, nil }, }, { Name: "reflect", Make: func(bench Benchmark) (Target, error) { return Target{ GetHeroList: func() (interface{}, error) { heroes := []*DBHero{} GetListO(&heroes) return heroes, nil }, }, nil }, }, } ) RunBenchmark(b, compose(parallelisms, dataSizes, builders)) } func GetList(data interface{}) (err error) { var c *mongo.Cursor t := reflect.TypeOf(data) if t.Kind() == reflect.Ptr { t = t.Elem() } if t.Kind() == reflect.Slice { t = t.Elem() } else { err = fmt.Errorf("Input param is not a slice") } sl := reflect.ValueOf(data) if t.Kind() == reflect.Ptr { sl = sl.Elem() } st := sl.Type() sliceType := st.Elem() if sliceType.Kind() == reflect.Ptr { sliceType = sliceType.Elem() } //query from mgo // if c, err = mdb.Mgo().Find(core.SqlTable("hero"), bson.M{}); err != nil { if c, err = mgoDb.Collection("hreo").Find(context.Background(), bson.M{}); err != nil { return err } else { var temp map[string]interface{} = make(map[string]interface{}) for c.Next(context.Background()) { _id := c.Current.Lookup("_id").StringValue() if sl.Len() < sl.Cap() { sl.Set(sl.Slice(0, sl.Len()+1)) elem := sl.Index(sl.Len() - 1) if elem.IsNil() { elem.Set(reflect.New(sliceType)) } if err = c.Decode(elem.Elem().Addr().Interface()); err != nil { return } temp[_id] = elem.Elem().Addr().Interface() continue } elem := reflect.New(sliceType) sl.Set(reflect.Append(sl, elem)) if err = c.Decode(elem.Elem().Addr().Interface()); err != nil { return } temp[_id] = elem.Elem().Addr().Interface() } if len(temp) == 0 { //没有数据自己返回 return } } return err } func GetListO(data interface{}) (err error) { var c *mongo.Cursor t := reflect.TypeOf(data) if t.Kind() == reflect.Ptr { t = t.Elem() } if t.Kind() == reflect.Slice { t = t.Elem() } else { err = fmt.Errorf("Input param is not a slice") } sl := reflect.ValueOf(data) if t.Kind() == reflect.Ptr { sl = sl.Elem() } st := sl.Type() sliceType := st.Elem() if sliceType.Kind() == reflect.Ptr { sliceType = sliceType.Elem() } //query from mgo if c, err = mdb.Mgo().Find(core.SqlTable("hero"), bson.M{}); err != nil { // if c, err = mgoDb.Collection("hreo").Find(context.Background(), bson.M{}); err != nil { return err } else { var temp map[string]interface{} = make(map[string]interface{}) for c.Next(context.Background()) { _id := c.Current.Lookup("_id").StringValue() if sl.Len() < sl.Cap() { sl.Set(sl.Slice(0, sl.Len()+1)) elem := sl.Index(sl.Len() - 1) if elem.IsNil() { elem.Set(reflect.New(sliceType)) } if err = c.Decode(elem.Elem().Addr().Interface()); err != nil { return } temp[_id] = elem.Elem().Addr().Interface() continue } elem := reflect.New(sliceType) sl.Set(reflect.Append(sl, elem)) if err = c.Decode(elem.Elem().Addr().Interface()); err != nil { return } temp[_id] = elem.Elem().Addr().Interface() } if len(temp) == 0 { //没有数据自己返回 return } } return err } func GetList2(data interface{}) (err error) { // c, err := mdb.Mgo().Find(core.SqlTable("hero"), bson.M{}) c, err := mgoDb.Collection("hero").Find(context.Background(), bson.M{}) if err != nil { fmt.Println(err) return } // defer c.Close(context.Background()) list := make([]interface{}, 0) for c.Next(context.Background()) { val := reflect.ValueOf(data).Interface() if err = c.Decode(val); err != nil { continue } list = append(list, val) } return } func GetList3(data any) []any { // c, err := mdb.Mgo().Collection("hero").Find(context.Background(), bson.M{}) c, err := mgoDb.Collection("hero").Find(context.Background(), bson.M{}) if err != nil { fmt.Println(err) } defer c.Close(context.Background()) list := make([]any, 0) for c.Next(context.Background()) { _val := reflect.ValueOf(data).Interface() err2 := c.Decode(_val) if err2 != nil { continue } list = append(list, _val) } return list } func GetList4(data *DBHero) []any { // c, err := mdb.Mgo().Find(core.SqlTable("hero"), bson.M{}) c, err := mgoDb.Collection("hero").Find(context.Background(), bson.M{}) if err != nil { fmt.Println(err) } defer c.Close(context.Background()) list := make([]any, 0) for c.Next(context.Background()) { err2 := c.Decode(data) if err2 != nil { continue } list = append(list, data) } return list } func BenchmarkSimple(b *testing.B) { // f, _ := os.Create("c://pprof2") // pprof.WriteHeapProfile(f) // defer f.Close() for i := 0; i < b.N; i++ { GetList4(new(DBHero)) } }