Skip to content

Commit 673a6f8

Browse files
rsneddsymonds
authored andcommitted
s2: Add Benchmarks for RegionCoverer.
Cap and Cell are ~O(1) on time and memory bytes and allocs. CellUnions end up at ~O(n) on time, and ~O(1) on memory bytes and allocs. Loops up to 256 edges are ~O(1) on time and memory bytes and allocs. For Loops beyond ~256 edges, there is a massive jump in time, memory and allocs and then moves to ~O(n log n). BenchmarkRegionCovererCoveringLoop/Loop-4-edges-42 64058 18569 ns/op 1904 B/op 42 allocs/op BenchmarkRegionCovererCoveringLoop/Loop-8-edges-42 53868 21499 ns/op 1972 B/op 44 allocs/op BenchmarkRegionCovererCoveringLoop/Loop-32-edges-42 71096 19208 ns/op 1900 B/op 43 allocs/op BenchmarkRegionCovererCoveringLoop/Loop-64-edges-42 67424 15791 ns/op 2184 B/op 45 allocs/op BenchmarkRegionCovererCoveringLoop/Loop-128-edges-42 66159 18145 ns/op 2847 B/op 51 allocs/op BenchmarkRegionCovererCoveringLoop/Loop-256-edges-42 43219 24792 ns/op 5484 B/op 71 allocs/op BenchmarkRegionCovererCoveringLoop/Loop-512-edges-42 1048 986620 ns/op 331277 B/op 2555 allocs/op BenchmarkRegionCovererCoveringLoop/Loop-1024-edges-42 747 1996238 ns/op 723120 B/op 5362 allocs/op BenchmarkRegionCovererCoveringLoop/Loop-2048-edges-42 297 4358194 ns/op 1869751 B/op 10740 allocs/op BenchmarkRegionCovererCoveringLoop/Loop-4096-edges-42 136 8244599 ns/op 4250742 B/op 21618 allocs/op Signed-off-by: David Symonds <dsymonds@golang.org>
1 parent 926b01c commit 673a6f8

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

s2/regioncoverer_test.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package s2
1616

1717
import (
18+
"fmt"
1819
"math"
1920
"math/rand"
2021
"reflect"
@@ -193,6 +194,87 @@ func TestRegionCovererSimpleRegionCovering(t *testing.T) {
193194
}
194195
}
195196

197+
const numCoveringBMRegions = 1000
198+
199+
func BenchmarkRegionCovererCoveringCap(b *testing.B) {
200+
benchmarkRegionCovererCovering(b, func(n int) string {
201+
return fmt.Sprintf("Cap%d", n)
202+
},
203+
func(n int) []Region {
204+
regions := make([]Region, numCoveringBMRegions)
205+
for i := 0; i < numCoveringBMRegions; i++ {
206+
regions[i] = randomCap(0.1*AvgAreaMetric.Value(maxLevel), 4*math.Pi)
207+
}
208+
return regions
209+
})
210+
}
211+
212+
func BenchmarkRegionCovererCoveringCell(b *testing.B) {
213+
benchmarkRegionCovererCovering(b, func(n int) string {
214+
return fmt.Sprintf("Cell%d", n)
215+
},
216+
func(n int) []Region {
217+
regions := make([]Region, numCoveringBMRegions)
218+
for i := 0; i < numCoveringBMRegions; i++ {
219+
regions[i] = CellFromCellID(randomCellIDForLevel(maxLevel - randomUniformInt(n)))
220+
}
221+
return regions
222+
})
223+
}
224+
225+
func BenchmarkRegionCovererCoveringLoop(b *testing.B) {
226+
benchmarkRegionCovererCovering(b, func(n int) string {
227+
return fmt.Sprintf("Loop-%d-edges", int(math.Pow(2.0, float64(n))))
228+
},
229+
func(n int) []Region {
230+
size := int(math.Pow(2.0, float64(n)))
231+
regions := make([]Region, numCoveringBMRegions)
232+
for i := 0; i < numCoveringBMRegions; i++ {
233+
regions[i] = RegularLoop(randomPoint(), kmToAngle(10.0), size)
234+
}
235+
return regions
236+
})
237+
}
238+
239+
func BenchmarkRegionCovererCoveringCellUnion(b *testing.B) {
240+
benchmarkRegionCovererCovering(b, func(n int) string {
241+
return fmt.Sprintf("CellUnion-%d-cells", int(math.Pow(2.0, float64(n))))
242+
},
243+
func(n int) []Region {
244+
size := int(math.Pow(2.0, float64(n)))
245+
regions := make([]Region, numCoveringBMRegions)
246+
for i := 0; i < numCoveringBMRegions; i++ {
247+
cu := randomCellUnion(size)
248+
regions[i] = &cu
249+
}
250+
return regions
251+
})
252+
}
253+
254+
// TODO(roberts): Add more benchmarking that changes the values in the coverer (min/max level, # cells).
255+
256+
// benchmark Covering using the supplied func to generate a slice of random Regions of
257+
// the given type to choose from for the benchmark.
258+
//
259+
// e.g. Loops with [4..~2^n] edges, CellUnions of 2^n random Cells, random Cells and Caps
260+
func benchmarkRegionCovererCovering(b *testing.B, genLabel func(n int) string, genRegions func(n int) []Region) {
261+
rc := &RegionCoverer{MinLevel: 0, MaxLevel: 30, LevelMod: 1, MaxCells: 8}
262+
263+
// Range over a variety of region complexities.
264+
for n := 2; n <= 16; n++ {
265+
b.Run(genLabel(n),
266+
func(b *testing.B) {
267+
b.StopTimer()
268+
regions := genRegions(n)
269+
l := len(regions)
270+
b.StartTimer()
271+
for i := 0; i < b.N; i++ {
272+
rc.Covering(regions[i%l])
273+
}
274+
})
275+
}
276+
}
277+
196278
// TODO(roberts): Differences from C++
197279
// func TestRegionCovererAccuracy(t *testing.T) {
198280
// func TestRegionCovererFastCoveringHugeFixedLevelCovering(t *testing.T) {

0 commit comments

Comments
 (0)