-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbench_test.go
117 lines (102 loc) · 2.14 KB
/
bench_test.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
// Copyright (c) 2015, Michael J. Fromberger
package shell_test
import (
"bytes"
"fmt"
"math"
"math/rand"
"strings"
"testing"
"github.com/creachadair/mds/shell"
)
var input string
// Generate a long random string with balanced quotations for perf testing.
func init() {
var buf bytes.Buffer
src := rand.NewSource(12345)
r := rand.New(src)
const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789 \t\n\n\n"
pick := func(f float64) byte {
pos := math.Ceil(f*float64(len(alphabet))) - 1
return alphabet[int(pos)]
}
const inputLen = 100000
var quote struct {
q byte
n int
}
for range inputLen {
if quote.n == 0 {
q := r.Float64()
if q < .1 {
quote.q = '"'
quote.n = r.Intn(256)
buf.WriteByte('"')
continue
} else if q < .15 {
quote.q = '\''
quote.n = r.Intn(256)
buf.WriteByte('\'')
continue
}
}
buf.WriteByte(pick(r.Float64()))
if quote.n > 0 {
quote.n--
if quote.n == 0 {
buf.WriteByte(quote.q)
}
}
}
input = buf.String()
}
func BenchmarkSplit(b *testing.B) {
var lens []int
for i := 1; i < len(input); i *= 4 {
lens = append(lens, i)
}
lens = append(lens, len(input))
s := shell.NewScanner(nil)
b.ResetTimer()
for _, n := range lens {
b.Run(fmt.Sprintf("len_%d", n), func(b *testing.B) {
for range b.N {
s.Reset(strings.NewReader(input[:n]))
s.Each(ignore)
}
})
}
}
func BenchmarkQuote(b *testing.B) {
const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789 \t\n\n\n"
src := rand.NewSource(67890)
r := rand.New(src)
var buf bytes.Buffer
for range 100000 {
switch v := r.Float64(); {
case v < 0.5:
buf.WriteByte('\'')
case v < 0.1:
buf.WriteByte('"')
case v < 0.15:
buf.WriteByte('\\')
default:
pos := math.Ceil(r.Float64()*float64(len(alphabet))) - 1
buf.WriteByte(alphabet[int(pos)])
}
}
input := buf.String()
parts, _ := shell.Split(input)
b.Logf("Input length: %d bytes, %d tokens", len(input), len(parts))
b.Run("Quote", func(b *testing.B) {
for range b.N {
shell.Quote(input)
}
})
b.Run("Join", func(b *testing.B) {
for range b.N {
shell.Join(parts)
}
})
}
func ignore(string) bool { return true }