dongxian1921
dongxian1921
2018-07-19 21:23
浏览 157
已采纳

如何在Go中获取包含数据结构的结构的大小?

I'm currently trying to get the size of a complex struct in Go.

I've read solutions that use reflect and unsafe, but neither of these help with structs that contain arrays or maps (or any other field that's a pointer to an underlying data structure).

Example:

type testStruct struct {
    A     int
    B     string
    C     struct{}
    items map[string]string
}

How would I find out the correct byte size of the above if items contains a few values in it?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • doushao8421
    doushao8421 2018-07-19 22:13
    已采纳

    You can get very close to the amount of memory required by the structure and its content by using the package reflect. You need to iterate over the fields and obtain the size of each field. For example:

    func getSize(v interface{}) int {
        size := int(reflect.TypeOf(v).Size())
        switch reflect.TypeOf(v).Kind() {
        case reflect.Slice:
            s := reflect.ValueOf(v)
            for i := 0; i < s.Len(); i++ {
                size += getSize(s.Index(i).Interface())
            }
        case reflect.Map:
            s := reflect.ValueOf(v)
            keys := s.MapKeys()
            size += int(float64(len(keys)) * 10.79) // approximation from https://golang.org/src/runtime/hashmap.go
            for i := range(keys) {
                size += getSize(keys[i].Interface()) + getSize(s.MapIndex(keys[i]).Interface())
            }
        case reflect.String:
            size += reflect.ValueOf(v).Len()
        case reflect.Struct:
            s := reflect.ValueOf(v)
            for i := 0; i < s.NumField(); i++ {
                if s.Field(i).CanInterface() {
                    size += getSize(s.Field(i).Interface())
                }
            }
        }
        return size
    }
    

    This obtains the size of v using reflect and then, for the supported types in this example (slices, maps, strings, and structs), it computes the memory required by the content stored in them. You would need to add here other types that you need to support.

    There are a few details to work out:

    1. Private fields are not counted.
    2. For structs we are double-counting the basic types.

    For number two, you can filter them out before doing the recursive call when handling structs, you can check the kinds in the documentation for the reflect package.

    点赞 评论

相关推荐