Skip to content

Commit ea28036

Browse files
committed
adding bench
1 parent e6f35a7 commit ea28036

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

cppcon2025/go/parse_twitter.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"io/ioutil"
7+
"os"
8+
"time"
9+
)
10+
11+
type TwitterUser struct {
12+
ID uint64 `json:"id"`
13+
Name string `json:"name"`
14+
ScreenName string `json:"screen_name"`
15+
Location string `json:"location"`
16+
Description string `json:"description"`
17+
FollowersCount uint64 `json:"followers_count"`
18+
FriendsCount uint64 `json:"friends_count"`
19+
Verified bool `json:"verified"`
20+
StatusesCount uint64 `json:"statuses_count"`
21+
}
22+
23+
type Status struct {
24+
User TwitterUser `json:"user"`
25+
}
26+
27+
type TwitterData struct {
28+
Statuses []Status `json:"statuses"`
29+
}
30+
31+
// Benchmark parsing of twitter.json and report speed in GB/s
32+
func main() {
33+
filename := "twitter.json"
34+
file, err := os.Open(filename)
35+
if err != nil {
36+
fmt.Println("Error opening file:", err)
37+
return
38+
}
39+
defer file.Close()
40+
41+
bytes, err := ioutil.ReadAll(file)
42+
if err != nil {
43+
fmt.Println("Error reading file:", err)
44+
return
45+
}
46+
47+
// Warmup parse
48+
var warmup TwitterData
49+
if err := json.Unmarshal(bytes, &warmup); err != nil {
50+
fmt.Println("Error parsing JSON:", err)
51+
return
52+
}
53+
54+
// Benchmark loop
55+
const iterations = 1000
56+
var totalBytes int64 = int64(len(bytes)) * iterations
57+
start := now()
58+
for i := 0; i < iterations; i++ {
59+
var data TwitterData
60+
if err := json.Unmarshal(bytes, &data); err != nil {
61+
fmt.Println("Error parsing JSON on iteration", i, ":", err)
62+
return
63+
}
64+
}
65+
elapsed := since(start)
66+
gb := float64(totalBytes) / 1e9
67+
seconds := elapsed.Seconds()
68+
speed := gb / seconds * 1000 // Convert GB/s to MB/s
69+
fmt.Printf("Parsed %.2f GB in %.3f seconds (%.2f MB/s)\n", gb, seconds, speed)
70+
}
71+
72+
// now returns current time
73+
func now() Time {
74+
return Time{t: timeNow()}
75+
}
76+
77+
// since returns duration since start
78+
func since(start Time) Duration {
79+
return Duration{d: timeSince(start.t)}
80+
}
81+
82+
// Time and Duration wrappers for benchmarking
83+
type Time struct{ t interface{} }
84+
type Duration struct{ d interface{} }
85+
86+
func (d Duration) Seconds() float64 {
87+
switch v := d.d.(type) {
88+
case float64:
89+
return v
90+
case int64:
91+
return float64(v) / 1e9
92+
default:
93+
return 0
94+
}
95+
}
96+
97+
// Use Go's time package
98+
func timeNow() interface{} { return time.Now() }
99+
func timeSince(t interface{}) interface{} {
100+
if tt, ok := t.(time.Time); ok {
101+
return float64(time.Since(tt).Nanoseconds()) / 1e9
102+
}
103+
return 0
104+
}

0 commit comments

Comments
 (0)