commit 0e5dd520cbb976828729dfba8aaf69e48c00aebc Author: Lucien Coffe Date: Fri May 26 09:43:36 2023 +0200 init diff --git a/cmd/estimate/main.go b/cmd/estimate/main.go new file mode 100644 index 0000000..7a75e26 --- /dev/null +++ b/cmd/estimate/main.go @@ -0,0 +1,39 @@ +package main + +import ( + "fmt" + "math/rand" + "os" + "strconv" + + "git.intruders.space/bot/mapsize" +) + +func main() { + if len(os.Args) < 2 { + panic("need argument") + } + + n, err := strconv.Atoi(os.Args[1]) + if err != nil { + panic("bad argument") + } + + m := make(map[string]string) + ms := mapsize.New() + + for i := 0; i < n*1_000_000; i++ { + k := strconv.FormatUint(rand.Uint64(), 10) + v := "abc" + + m[k] = v + ms.Add(len(k), len(v)) + } + + fmt.Println("do you want an estimate? (y/y)") + var c byte + fmt.Scan(&c) + + fmt.Printf("\nestimate: %d kB\n", ms.Size()/1024) + +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..03e04e8 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module git.intruders.space/bot/mapsize + +go 1.20 diff --git a/mapsize.go b/mapsize.go new file mode 100644 index 0000000..78ca27a --- /dev/null +++ b/mapsize.go @@ -0,0 +1,35 @@ +package mapsize + +import ( + "math" + "unsafe" +) + +type Mapsize struct { + ptrSize uint64 + intSize uint64 + dataSize uint64 + len uint64 +} + +func New() *Mapsize { + return &Mapsize{ + ptrSize: uint64(unsafe.Sizeof(&[]int{0}[0])), + intSize: uint64(unsafe.Sizeof(int(0))), + } +} + +func (m *Mapsize) Add(k, v int) { + m.len++ + // string: ptr=psize, cap=isize, len=isize + m.dataSize += uint64(k) + uint64(v) + 4*m.intSize + 2*m.ptrSize +} + +func (m *Mapsize) Size() uint64 { + hmapSize := m.intSize + 1 + 1 + 2 + 4 + m.ptrSize*4 + buckets := uint64(1 << uint(math.Ceil(math.Log2(float64(m.len))))) + + // entry overhead = key ptr, value ptr, hash, next + // bucket overhead = 2 ptr (overflow) + return hmapSize + m.dataSize + m.len*(4*m.ptrSize) + buckets*(2*m.ptrSize) +}