Helper programs to repro JSON deserialize mem use
JSON deserialize of arrays is inefficient for memory. This is a minimal reproducer to show that it uses lots more memory than expected. Build each program separately, run gen and then you can run goread for the repro and some memory usage stats.
This commit is contained in:
parent
1cbd2e9cfb
commit
f00970493d
31
src/cmd/jsondebug/common/helpers.go
Normal file
31
src/cmd/jsondebug/common/helpers.go
Normal file
@ -0,0 +1,31 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
const (
|
||||
NumItems = 300000
|
||||
ItemSize = 1024
|
||||
FileName = "input.json"
|
||||
)
|
||||
|
||||
type Foo struct {
|
||||
A []byte
|
||||
}
|
||||
|
||||
func PrintMemUsage() {
|
||||
var m runtime.MemStats
|
||||
|
||||
runtime.ReadMemStats(&m)
|
||||
// For info on each, see: https://golang.org/pkg/runtime/#MemStats
|
||||
fmt.Printf("Alloc = %v MiB", bToMb(m.Alloc))
|
||||
fmt.Printf("\tTotalAlloc = %v MiB", bToMb(m.TotalAlloc))
|
||||
fmt.Printf("\tSys = %v MiB", bToMb(m.Sys))
|
||||
fmt.Printf("\tNumGC = %v\n", m.NumGC)
|
||||
}
|
||||
|
||||
func bToMb(b uint64) uint64 {
|
||||
return b / 1024 / 1024
|
||||
}
|
||||
47
src/cmd/jsondebug/gen/gen.go
Normal file
47
src/cmd/jsondebug/gen/gen.go
Normal file
@ -0,0 +1,47 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/alcionai/corso/src/cmd/jsondebug/common"
|
||||
)
|
||||
|
||||
func main() {
|
||||
buf := make([]byte, common.ItemSize)
|
||||
data := make([]common.Foo, 0, common.NumItems)
|
||||
|
||||
for i := 0; i < common.NumItems; i++ {
|
||||
n, err := rand.Read(buf)
|
||||
if err != nil {
|
||||
fmt.Printf("Error reading random data: %v\n", err)
|
||||
return
|
||||
} else if n != common.ItemSize {
|
||||
fmt.Printf(
|
||||
"Short read for item data: wanted %d, got %d\n",
|
||||
common.ItemSize,
|
||||
n,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
item := common.Foo{A: buf}
|
||||
data = append(data, item)
|
||||
}
|
||||
|
||||
f, err := os.Create(common.FileName)
|
||||
if err != nil {
|
||||
fmt.Printf("Error making output file: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
enc := json.NewEncoder(f)
|
||||
if err := enc.Encode(data); err != nil {
|
||||
fmt.Printf("Error writing json to file: %v\n", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
30
src/cmd/jsondebug/goread/read.go
Normal file
30
src/cmd/jsondebug/goread/read.go
Normal file
@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/alcionai/corso/src/cmd/jsondebug/common"
|
||||
)
|
||||
|
||||
func main() {
|
||||
f, err := os.Open(common.FileName)
|
||||
if err != nil {
|
||||
fmt.Printf("Error opening input file: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
dec := json.NewDecoder(f)
|
||||
|
||||
output := []common.Foo{}
|
||||
|
||||
if err := dec.Decode(&output); err != nil {
|
||||
fmt.Printf("Error decoding input: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
common.PrintMemUsage()
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user