forked from dgraph-io/dgraph
/
benchmark.go
156 lines (124 loc) · 2.82 KB
/
benchmark.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package main
import (
"compress/gzip"
"encoding/binary"
"fmt"
"io"
"os"
"sort"
"time"
"github.com/dgraph-io/dgraph/bp128"
"github.com/dgraph-io/dgraph/x"
)
const (
// chunkByteSize is the number
// of bytes per chunk of data.
chunkByteSize = 262144
)
func read(filename string) []int {
f, err := os.Open(filename)
if err != nil {
panic(err)
}
defer f.Close()
fgzip, err := gzip.NewReader(f)
if err != nil {
panic(err)
}
defer fgzip.Close()
buf := make([]byte, 4)
_, err = fgzip.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
ndata := binary.LittleEndian.Uint32(buf)
data := make([]int, ndata)
for i := range data {
_, err = fgzip.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
data[i] = int(binary.LittleEndian.Uint32(buf))
}
return data
}
type chunks struct {
intSize int
data [][]uint64
length int
}
func chunkify64(data []int) *chunks {
const chunkLen = chunkByteSize / 8
nchunks := len(data) / chunkLen
cdata := make([][]uint64, nchunks)
n := 0
for i := range cdata {
chunk := make([]uint64, chunkLen)
for j := range chunk {
chunk[j] = uint64(data[n])
n++
}
cdata[i] = chunk
}
return &chunks{64, cdata, n}
}
func benchmarkPack(trials int, chunks *chunks) int {
times := make([]int, trials)
for i := range times {
start := time.Now()
for _, c := range chunks.data {
bp128.DeltaPack(c)
}
times[i] = int(time.Since(start).Nanoseconds())
}
sort.Ints(times)
tmedian := times[len(times)/2]
speed := (float64(chunks.length) / float64(tmedian)) * 1e3
return int(speed)
}
func benchmarkUnpack(trials int, chunks *chunks) int {
packed := make([][]byte, len(chunks.data))
for i, c := range chunks.data {
packed[i] = bp128.DeltaPack(c)
}
out := make([]uint64, chunkByteSize/8)
times := make([]int, trials)
for i := range times {
start := time.Now()
for _, p := range packed {
bp128.DeltaUnpack(p, out)
}
times[i] = int(time.Since(start).Nanoseconds())
}
// Check if both input and output are equal
for i, c := range chunks.data {
bp128.DeltaUnpack(packed[i], out)
for j := 0; j < len(c); j++ {
if c[j] != out[j] {
x.Fatalf("Something wrong %+v \n%+v\n %+v\n", len(c), len(out), j)
}
}
}
sort.Ints(times)
tmedian := times[len(times)/2]
speed := (float64(chunks.length) / float64(tmedian)) * 1e3
return int(speed)
}
func fmtBenchmark(name string, speed int) {
const maxlen = 25
fmt.Printf("%-*s\t%5d mis\n", maxlen, name, speed)
}
func main() {
data := read("../data/clustered1M.bin.gz")
if !sort.IsSorted(sort.IntSlice(data)) {
panic("test data must be sorted")
}
chunks64 := chunkify64(data)
data = nil
mis := 0
const ntrials = 1000
mis = benchmarkPack(ntrials, chunks64)
fmtBenchmark("BenchmarkDeltaPack64", mis)
mis = benchmarkUnpack(ntrials, chunks64)
fmtBenchmark("BenchmarkDeltaUnPack64", mis)
}