Ari*_*vil 0 optimization performance struct transactions go
我的API服务器接受post请求,请求体是JSON,所以我创建两个struct对象来接受JSON字符串并将其持久化到database.But每次我接受一个请求我需要一遍又一遍地创建struct对象,我试着清除结构而不是重新创建它.演示代码如下:
//The two struct
type Card struct {
Number string
Type string
}
type Person struct {
Name string
Cards []Card
}
var p Person
//parse JSON to the struct object
func init() {
str := `{"name":"aaa","cards":[{"number":"1","type":"visa"},{"number":"2","type":"mastercard"}]}`
json.Unmarshal([]byte(str), &p)
}
func PersistToDatabase() {
var err error
tx, err := db.Begin()
if err != nil {
return
}
defer func() {
if err != nil && tx != nil {
if err := tx.Rollback(); err != nil {
return
}
}
}
finish := make(chan bool)
stmt1, err := tx.Prepare(`insert into tb1(name) values(?)`)
if err != nil {
panic(err.Error())
}
defer stmt1.Close()
stmt2, err := tx.Prepare(`insert into tb2(name, num, type) values(?, ?, ?)`)
if err != nil {
panic(err.Error())
}
defer stmt2.Close()
go func() {
defer func() { finish <- true }()
if _, err = stmt1.Exec(p.name); err != nil {
log.Println("stmt1.Exec: ", err.Error())
return
}
for _, x := range p.Cards {
if _, err = stmt2.Exec(p.name, x.Number, x.Type); err != nil {
log.Println("stmt2.Exec: ", err.Error())
return
}
}
}
<-finish
//clear struct object
p.Name = ""
p.Cards = nil //have anything do this better?
}
Run Code Online (Sandbox Code Playgroud)
在代码底部我清除了Name元素,但是让Cards元素成为nil,我该怎样才能做得更好?我的数据库操作有问题吗?
结构不是对象[1].虽然从根本上说它们都是以某种方式对有序数据进行的混合,但结构实际上只是一个变量列表.没有调用构造函数.没有超出其成员元素的内存,并且它没有在任何特殊的地方分配.(即使在大多数OO语言中,这可能并不太昂贵,优化器有时很酷)如果我有
type A struct {
I int
S string
}
var MyA A
Run Code Online (Sandbox Code Playgroud)
它并没有太大的不同
var (
I int
S string
)
Run Code Online (Sandbox Code Playgroud)
写一个类型的零结构MyA = A{}实际上相当于做MyA.I = 0; MyA.S = "",而这实际上相当于I = 0; S = "".执行上述任何操作都不应存在(重大)性能开销.
这并不意味着结构没有用.从概念上讲,它们在定义方法时非常有用,用于填充数据,例如像JSON这样的情况.但他们不是很明显不同.最后,这是最重要的事情,你在这段代码中描述了一个重要的性能瓶颈吗?如果没有(我怀疑没有),不要担心,它可能没问题.:)
[1] Java或C#风格的对象,理论上(即使不在实践中)更昂贵.不是不同的C++对象(更像是Go结构).