Skip to content

Commit

Permalink
Adding benchmark tests over some popular queries (blevesearch#1755)
Browse files Browse the repository at this point in the history
Here're results on my computer:
```
[12:52:04] AD: ~/Documents/go/src/github.com/blevesearch/bleve $ go test -run=BenchmarkQuery -bench=BenchmarkQuery -v
goos: darwin
goarch: amd64
pkg: github.com/blevesearch/bleve/v2
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkQueryTerm
BenchmarkQueryTerm-12                     181676              6309 ns/op            4130 B/op         59 allocs/op
BenchmarkQueryTermRange
BenchmarkQueryTermRange-12                 72004             16440 ns/op            7286 B/op         94 allocs/op
BenchmarkQueryWildcard
BenchmarkQueryWildcard-12                   4686            251194 ns/op          124294 B/op        291 allocs/op
BenchmarkQueryNumericRange
BenchmarkQueryNumericRange-12              59023             20151 ns/op           12760 B/op        155 allocs/op
BenchmarkQueryDateRange
BenchmarkQueryDateRange-12                 34382             33578 ns/op           18647 B/op        256 allocs/op
BenchmarkQueryGeoDistance
BenchmarkQueryGeoDistance-12               24669             41800 ns/op           26878 B/op        279 allocs/op
BenchmarkQueryGeoBoundingBox
BenchmarkQueryGeoBoundingBox-12            14122             84857 ns/op           47915 B/op        352 allocs/op
PASS
ok      github.com/blevesearch/bleve/v2 507.927s

```
  • Loading branch information
abhinavdangeti authored Nov 17, 2022
1 parent 56dc9b2 commit 7e6d848
Showing 1 changed file with 393 additions and 0 deletions.
393 changes: 393 additions & 0 deletions query_bench_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,393 @@
// Copyright (c) 2022 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package bleve

import (
"strconv"
"testing"
"time"

"github.com/blevesearch/bleve/v2/analysis/analyzer/keyword"
"github.com/blevesearch/bleve/v2/mapping"
)

func BenchmarkQueryTerm(b *testing.B) {
tmpIndexPath := createTmpIndexPath(b)
defer cleanupTmpIndexPath(b, tmpIndexPath)

fm := mapping.NewTextFieldMapping()
fm.Analyzer = keyword.Name
dmap := mapping.NewDocumentMapping()
dmap.AddFieldMappingsAt("text", fm)
imap := mapping.NewIndexMapping()
imap.DefaultMapping = dmap

idx, err := New(tmpIndexPath, imap)
if err != nil {
b.Fatal(err)
}

defer func() {
err = idx.Close()
if err != nil {
b.Fatal(err)
}
}()

members := []string{"abc", "abcdef", "ghi", "jkl", "jklmno"}
for i := 0; i < 100; i++ {
if err = idx.Index(strconv.Itoa(i),
map[string]interface{}{"text": members[i%len(members)]}); err != nil {
b.Fatal(err)
}
}

b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
q := NewTermQuery(members[i%len(members)])
q.SetField("text")
req := NewSearchRequest(q)
if _, err = idx.Search(req); err != nil {
b.Fatal(err)
}
}
}

func BenchmarkQueryTermRange(b *testing.B) {
tmpIndexPath := createTmpIndexPath(b)
defer cleanupTmpIndexPath(b, tmpIndexPath)

fm := mapping.NewTextFieldMapping()
fm.Analyzer = keyword.Name
dmap := mapping.NewDocumentMapping()
dmap.AddFieldMappingsAt("text", fm)
imap := mapping.NewIndexMapping()
imap.DefaultMapping = dmap

idx, err := New(tmpIndexPath, imap)
if err != nil {
b.Fatal(err)
}

defer func() {
err = idx.Close()
if err != nil {
b.Fatal(err)
}
}()

members := []string{"abc", "abcdef", "ghi", "jkl", "jklmno"}
for i := 0; i < 100; i++ {
if err = idx.Index(strconv.Itoa(i),
map[string]interface{}{"text": members[i%len(members)]}); err != nil {
b.Fatal(err)
}
}

b.ReportAllocs()
b.ResetTimer()

inclusive := true
for i := 0; i < b.N; i++ {
q := NewTermRangeInclusiveQuery(
members[i%(len(members)-2)],
members[(i+2)%(len(members)-2)],
&inclusive,
&inclusive,
)
q.SetField("text")
req := NewSearchRequest(q)
if _, err = idx.Search(req); err != nil {
b.Fatal(err)
}
}
}

func BenchmarkQueryWildcard(b *testing.B) {
tmpIndexPath := createTmpIndexPath(b)
defer cleanupTmpIndexPath(b, tmpIndexPath)

fm := mapping.NewTextFieldMapping()
fm.Analyzer = keyword.Name
dmap := mapping.NewDocumentMapping()
dmap.AddFieldMappingsAt("text", fm)
imap := mapping.NewIndexMapping()
imap.DefaultMapping = dmap

idx, err := New(tmpIndexPath, imap)
if err != nil {
b.Fatal(err)
}

defer func() {
err = idx.Close()
if err != nil {
b.Fatal(err)
}
}()

members := []string{"abc", "abcdef", "ghi", "jkl", "jklmno"}
for i := 0; i < 100; i++ {
if err = idx.Index(strconv.Itoa(i),
map[string]interface{}{"text": members[i%len(members)]}); err != nil {
b.Fatal(err)
}
}

wildcards := []string{"ab*", "jk*"}

b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
q := NewWildcardQuery(wildcards[i%len(wildcards)])
q.SetField("text")
req := NewSearchRequest(q)
if _, err = idx.Search(req); err != nil {
b.Fatal(err)
}
}
}

func BenchmarkQueryNumericRange(b *testing.B) {
tmpIndexPath := createTmpIndexPath(b)
defer cleanupTmpIndexPath(b, tmpIndexPath)

fm := mapping.NewNumericFieldMapping()
dmap := mapping.NewDocumentMapping()
dmap.AddFieldMappingsAt("number", fm)
imap := mapping.NewIndexMapping()
imap.DefaultMapping = dmap

idx, err := New(tmpIndexPath, imap)
if err != nil {
b.Fatal(err)
}

defer func() {
err = idx.Close()
if err != nil {
b.Fatal(err)
}
}()

for i := 0; i < 100; i++ {
if err = idx.Index(strconv.Itoa(i),
map[string]interface{}{"number": i}); err != nil {
b.Fatal(err)
}
}

b.ReportAllocs()
b.ResetTimer()

inclusive := true
for i := 0; i < b.N; i++ {
start := float64(i % 90)
end := float64((i + 10) % 90)
q := NewNumericRangeInclusiveQuery(&start, &end, &inclusive, &inclusive)
q.SetField("number")
req := NewSearchRequest(q)
if _, err = idx.Search(req); err != nil {
b.Fatal(err)
}
}
}

func BenchmarkQueryDateRange(b *testing.B) {
tmpIndexPath := createTmpIndexPath(b)
defer cleanupTmpIndexPath(b, tmpIndexPath)

fm := mapping.NewDateTimeFieldMapping()
dmap := mapping.NewDocumentMapping()
dmap.AddFieldMappingsAt("date", fm)
imap := mapping.NewIndexMapping()
imap.DefaultMapping = dmap

idx, err := New(tmpIndexPath, imap)
if err != nil {
b.Fatal(err)
}

defer func() {
err = idx.Close()
if err != nil {
b.Fatal(err)
}
}()

members := []string{
"2022-11-16T18:45:45Z",
"2022-11-17T18:45:45Z",
"2022-11-18T18:45:45Z",
"2022-11-19T18:45:45Z",
"2022-11-20T18:45:45Z",
}
for i := 0; i < 100; i++ {
if err = idx.Index(strconv.Itoa(i),
map[string]interface{}{"date": members[i%len(members)]}); err != nil {
b.Fatal(err)
}
}

b.ReportAllocs()
b.ResetTimer()

inclusive := true
for i := 0; i < b.N; i++ {
start, _ := time.Parse("2006-01-02T12:00:00Z", members[i%(len(members)-2)])
end, _ := time.Parse("2006-01-02T12:00:00Z", members[(i+2)%(len(members)-2)])
q := NewDateRangeInclusiveQuery(start, end, &inclusive, &inclusive)
q.SetField("date")
req := NewSearchRequest(q)
if _, err = idx.Search(req); err != nil {
b.Fatal(err)
}
}
}

func BenchmarkQueryGeoDistance(b *testing.B) {
tmpIndexPath := createTmpIndexPath(b)
defer cleanupTmpIndexPath(b, tmpIndexPath)

fm := mapping.NewGeoPointFieldMapping()
dmap := mapping.NewDocumentMapping()
dmap.AddFieldMappingsAt("geo", fm)
imap := mapping.NewIndexMapping()
imap.DefaultMapping = dmap

idx, err := New(tmpIndexPath, imap)
if err != nil {
b.Fatal(err)
}

defer func() {
err = idx.Close()
if err != nil {
b.Fatal(err)
}
}()

members := [][]float64{
{-121.96713072883645, 37.380331474621045},
{-97.75518866579938, 30.38974491308761},
{-0.08653451918110022, 51.51063984942306},
{-2.230759791360498, 53.481514330841236},
{77.59542326042589, 12.97215865921956},
}
for i := 0; i < 100; i++ {
if err = idx.Index(strconv.Itoa(i),
map[string]interface{}{"geo": members[i%len(members)]}); err != nil {
b.Fatal(err)
}
}

b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
coordinates := members[i%len(members)]
q := NewGeoDistanceQuery(coordinates[0], coordinates[1], "1mi")
q.SetField("geo")
req := NewSearchRequest(q)
if _, err = idx.Search(req); err != nil {
b.Fatal(err)
}
}
}

func BenchmarkQueryGeoBoundingBox(b *testing.B) {
tmpIndexPath := createTmpIndexPath(b)
defer cleanupTmpIndexPath(b, tmpIndexPath)

fm := mapping.NewGeoPointFieldMapping()
dmap := mapping.NewDocumentMapping()
dmap.AddFieldMappingsAt("geo", fm)
imap := mapping.NewIndexMapping()
imap.DefaultMapping = dmap

idx, err := New(tmpIndexPath, imap)
if err != nil {
b.Fatal(err)
}

defer func() {
err = idx.Close()
if err != nil {
b.Fatal(err)
}
}()

members := [][]float64{
{-121.96713072883645, 37.380331474621045},
{-97.75518866579938, 30.38974491308761},
{-0.08653451918110022, 51.51063984942306},
{-2.230759791360498, 53.481514330841236},
{77.59542326042589, 12.97215865921956},
}
for i := 0; i < 100; i++ {
if err = idx.Index(strconv.Itoa(i),
map[string]interface{}{"geo": members[i%len(members)]}); err != nil {
b.Fatal(err)
}
}

boundingBoxes := []struct {
topLeft []float64
bottomRight []float64
}{
{
topLeft: []float64{-122.14424992609722, 37.49751487670511},
bottomRight: []float64{-121.78076546622579, 37.26963069737202},
},
{
topLeft: []float64{-97.85362236226437, 30.473743975245725},
bottomRight: []float64{-97.58691085968482, 30.285211697102895},
},
{
topLeft: []float64{-0.28538822102223094, 51.61106497119687},
bottomRight: []float64{0.16776748108466677, 51.395702237541286},
},
{
topLeft: []float64{-2.373683904907921, 53.54371945714075},
bottomRight: []float64{-2.134365533113197, 53.41788831720595},
},
{
topLeft: []float64{77.52617635172015, 13.037587208986437},
bottomRight: []float64{77.66508989028102, 12.924426170584738},
},
}

b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
topLeftCoordinates := boundingBoxes[i%len(boundingBoxes)].topLeft
bottomRightCoordinates := boundingBoxes[i%len(boundingBoxes)].bottomRight
q := NewGeoBoundingBoxQuery(
topLeftCoordinates[0],
topLeftCoordinates[1],
bottomRightCoordinates[0],
bottomRightCoordinates[1],
)
q.SetField("geo")
req := NewSearchRequest(q)
if _, err = idx.Search(req); err != nil {
b.Fatal(err)
}
}
}

0 comments on commit 7e6d848

Please sign in to comment.