1// Copyright 2013 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package go1
6
7import (
8	"math/rand"
9	"regexp"
10	"testing"
11)
12
13// benchmark based on regexp/exec_test.go
14
15var regexpText []byte
16
17func makeRegexpText(n int) []byte {
18	rand.Seed(0) // For reproducibility.
19	if len(regexpText) >= n {
20		return regexpText[:n]
21	}
22	regexpText = make([]byte, n)
23	for i := range regexpText {
24		if rand.Intn(30) == 0 {
25			regexpText[i] = '\n'
26		} else {
27			regexpText[i] = byte(rand.Intn(0x7E+1-0x20) + 0x20)
28		}
29	}
30	return regexpText
31}
32
33func benchmark(b *testing.B, re string, n int) {
34	r := regexp.MustCompile(re)
35	t := makeRegexpText(n)
36	b.ResetTimer()
37	b.SetBytes(int64(n))
38	for i := 0; i < b.N; i++ {
39		if r.Match(t) {
40			b.Fatal("match!")
41		}
42	}
43}
44
45const (
46	easy0  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ$"
47	easy1  = "A[AB]B[BC]C[CD]D[DE]E[EF]F[FG]G[GH]H[HI]I[IJ]J$"
48	medium = "[XYZ]ABCDEFGHIJKLMNOPQRSTUVWXYZ$"
49	hard   = "[ -~]*ABCDEFGHIJKLMNOPQRSTUVWXYZ$"
50)
51
52func BenchmarkRegexpMatchEasy0_32(b *testing.B)  { benchmark(b, easy0, 32<<0) }
53func BenchmarkRegexpMatchEasy0_1K(b *testing.B)  { benchmark(b, easy0, 1<<10) }
54func BenchmarkRegexpMatchEasy1_32(b *testing.B)  { benchmark(b, easy1, 32<<0) }
55func BenchmarkRegexpMatchEasy1_1K(b *testing.B)  { benchmark(b, easy1, 1<<10) }
56func BenchmarkRegexpMatchMedium_32(b *testing.B) { benchmark(b, medium, 1<<0) }
57func BenchmarkRegexpMatchMedium_1K(b *testing.B) { benchmark(b, medium, 1<<10) }
58func BenchmarkRegexpMatchHard_32(b *testing.B)   { benchmark(b, hard, 32<<0) }
59func BenchmarkRegexpMatchHard_1K(b *testing.B)   { benchmark(b, hard, 1<<10) }
60