英文:
How to get the size of struct and its contents in bytes in golang?
问题
我有一个结构体,假设如下:
type ASDF struct {
A uint64
B uint64
C uint64
D uint64
E uint64
F string
}
我创建了一个该结构体的切片:a := []ASDF{}
我对该结构体的切片进行操作(添加/删除/更新内容不同的结构体);如何获取该切片及其内容的总大小(以字节为单位,用于内存)?是否有内置的方法可以实现这一点,还是我需要手动使用unsafe.Sizeof
和len
函数进行计算?
英文:
I have a struct, say:
type ASDF struct {
A uint64
B uint64
C uint64
D uint64
E uint64
F string
}
I create a slice of that struct: a := []ASDF{}
I do operations on that slice of the struct (adding/removing/updating structs that vary in contents); how can I get the total size in bytes (for memory) of the slice and its contents? Is there a built-in to do this or do I need to manually run a calculation using unsafe.Sizeof
and then len
each string?
答案1
得分: 8
计算所有内存的大小,不包括垃圾收集器和其他开销。例如,
package main
import (
"fmt"
"unsafe"
)
type ASDF struct {
A uint64
B uint64
C uint64
D uint64
E uint64
F string
}
func (s *ASDF) size() int {
size := int(unsafe.Sizeof(*s))
size += len(s.F)
return size
}
func sizeASDF(s []ASDF) int {
size := 0
s = s[:cap(s)]
size += cap(s) * int(unsafe.Sizeof(s))
for i := range s {
size += (&s[i]).size()
}
return size
}
func main() {
a := []ASDF{}
b := ASDF{}
b.A = 1
b.B = 2
b.C = 3
b.D = 4
b.E = 5
b.F = "ASrtertetetetetetetDF"
fmt.Println((&b).size())
a = append(a, b)
c := ASDF{}
c.A = 10
c.B = 20
c.C = 30
c.D = 40
c.E = 50
c.F = "ASetDF"
fmt.Println((&c).size())
a = append(a, c)
fmt.Println(len(a))
fmt.Println(cap(a))
fmt.Println(sizeASDF(a))
}
输出:
69
54
2
2
147
http://play.golang.org/p/5z30vkyuNM
英文:
Sum the size of all memory, excluding garbage collector and other overhead. For example,
package main
import (
"fmt"
"unsafe"
)
type ASDF struct {
A uint64
B uint64
C uint64
D uint64
E uint64
F string
}
func (s *ASDF) size() int {
size := int(unsafe.Sizeof(*s))
size += len(s.F)
return size
}
func sizeASDF(s []ASDF) int {
size := 0
s = s[:cap(s)]
size += cap(s) * int(unsafe.Sizeof(s))
for i := range s {
size += (&s[i]).size()
}
return size
}
func main() {
a := []ASDF{}
b := ASDF{}
b.A = 1
b.B = 2
b.C = 3
b.D = 4
b.E = 5
b.F = "ASrtertetetetetetetDF"
fmt.Println((&b).size())
a = append(a, b)
c := ASDF{}
c.A = 10
c.B = 20
c.C = 30
c.D = 40
c.E = 50
c.F = "ASetDF"
fmt.Println((&c).size())
a = append(a, c)
fmt.Println(len(a))
fmt.Println(cap(a))
fmt.Println(sizeASDF(a))
}
Output:
69
54
2
2
147
答案2
得分: 3
很抱歉,如果你想要得到任何结果,unsafe.Sizeof
是唯一的选择。结构体的内存大小不是你应该依赖的。请注意,即使是unsafe.Sizeof
的结果也是不准确的:运行时可能会添加你无法观察到的数据头以帮助垃圾回收。
对于你的特定示例(查找缓存大小),我建议你使用一个对许多处理器都合理的静态大小。在几乎所有情况下,进行这种微观优化是得不偿失的。
英文:
I'm afraid to say that unsafe.Sizeof
is the way to go here if you want to get any result at all. The in-memory size of a structure is nothing you should rely on. Notice that even the result of unsafe.Sizeof
is inaccurate: The runtime may add headers to the data that you cannot observe to aid with garbage collection.
For your particular example (finding a cache size) I suggest you to go with a static size that is sensible for many processors. In almost all cases doing such micro-optimizations is not going to pay itself off.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论