如何在Go中使用清晰的结构值来优化性能?

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,我该怎样才能做得更好?我的数据库操作有问题吗?

Lin*_*ope 5

结构不是对象[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结构).

  • 不要怀疑:做度量.不要预先优化那些不可证明是瓶颈的东西. (4认同)