blob: 08d6bf4bdb06c99d9899c8ca87480e6d707d512f [file] [log] [blame]
rileya@google.com981b33a2012-09-05 18:36:17 +00001
2/*
3 * Copyright 2012 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
tfarinaf168b862014-06-19 12:32:29 -07009#include "Benchmark.h"
rileya@google.com981b33a2012-09-05 18:36:17 +000010#include "SkCanvas.h"
11#include "SkRTree.h"
12#include "SkRandom.h"
13#include "SkString.h"
14
15// confine rectangles to a smallish area, so queries generally hit something, and overlap occurs:
mtklein533eb782014-08-27 10:39:42 -070016static const SkScalar GENERATE_EXTENTS = 1000.0f;
rileya@google.com981b33a2012-09-05 18:36:17 +000017static const int NUM_BUILD_RECTS = 500;
18static const int NUM_QUERY_RECTS = 5000;
sglez@google.com8c902122013-08-30 17:27:47 +000019static const int GRID_WIDTH = 100;
rileya@google.com981b33a2012-09-05 18:36:17 +000020
mtklein533eb782014-08-27 10:39:42 -070021typedef SkRect (*MakeRectProc)(SkRandom&, int, int);
rileya@google.com981b33a2012-09-05 18:36:17 +000022
23// Time how long it takes to build an R-Tree either bulk-loaded or not
tfarinaf168b862014-06-19 12:32:29 -070024class RTreeBuildBench : public Benchmark {
rileya@google.com981b33a2012-09-05 18:36:17 +000025public:
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +000026 RTreeBuildBench(const char* name, MakeRectProc proc, bool bulkLoad,
mtklein8f8c25e2014-10-02 09:53:04 -070027 SkRTree* tree)
mtklein@google.com410e6e82013-09-13 19:52:27 +000028 : fTree(tree)
rileya@google.com981b33a2012-09-05 18:36:17 +000029 , fProc(proc)
rileya@google.com61348d12012-09-06 13:38:53 +000030 , fBulkLoad(bulkLoad) {
31 fName.append("rtree_");
32 fName.append(name);
33 fName.append("_build");
34 if (fBulkLoad) {
35 fName.append("_bulk");
36 }
37 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +000038
39 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
40 return backend == kNonRendering_Backend;
41 }
42
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +000043 virtual ~RTreeBuildBench() {
rileya@google.com48134582012-09-11 15:41:50 +000044 fTree->unref();
robertphillips@google.com07a05d52012-09-11 11:54:07 +000045 }
rileya@google.com981b33a2012-09-05 18:36:17 +000046protected:
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +000047 virtual const char* onGetName() SK_OVERRIDE {
rileya@google.com61348d12012-09-06 13:38:53 +000048 return fName.c_str();
rileya@google.com981b33a2012-09-05 18:36:17 +000049 }
commit-bot@chromium.org33614712013-12-03 18:17:16 +000050 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000051 SkRandom rand;
commit-bot@chromium.org33614712013-12-03 18:17:16 +000052 for (int i = 0; i < loops; ++i) {
rileya@google.com981b33a2012-09-05 18:36:17 +000053 for (int j = 0; j < NUM_BUILD_RECTS; ++j) {
mtklein6bd41962014-10-02 07:41:56 -070054 fTree->insert(j, fProc(rand, j, NUM_BUILD_RECTS), fBulkLoad);
rileya@google.com981b33a2012-09-05 18:36:17 +000055 }
56 fTree->flushDeferredInserts();
57 fTree->clear();
58 }
59 }
60private:
mtklein8f8c25e2014-10-02 09:53:04 -070061 SkRTree* fTree;
rileya@google.com981b33a2012-09-05 18:36:17 +000062 MakeRectProc fProc;
rileya@google.com61348d12012-09-06 13:38:53 +000063 SkString fName;
rileya@google.com981b33a2012-09-05 18:36:17 +000064 bool fBulkLoad;
tfarinaf168b862014-06-19 12:32:29 -070065 typedef Benchmark INHERITED;
rileya@google.com981b33a2012-09-05 18:36:17 +000066};
67
68// Time how long it takes to perform queries on an R-Tree, bulk-loaded or not
tfarinaf168b862014-06-19 12:32:29 -070069class RTreeQueryBench : public Benchmark {
rileya@google.com981b33a2012-09-05 18:36:17 +000070public:
71 enum QueryType {
72 kSmall_QueryType, // small queries
73 kLarge_QueryType, // large queries
74 kRandom_QueryType,// randomly sized queries
75 kFull_QueryType // queries that cover everything
76 };
77
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +000078 RTreeQueryBench(const char* name, MakeRectProc proc, bool bulkLoad,
mtklein8f8c25e2014-10-02 09:53:04 -070079 QueryType q, SkRTree* tree)
mtklein@google.com410e6e82013-09-13 19:52:27 +000080 : fTree(tree)
rileya@google.com981b33a2012-09-05 18:36:17 +000081 , fProc(proc)
rileya@google.com981b33a2012-09-05 18:36:17 +000082 , fBulkLoad(bulkLoad)
83 , fQuery(q) {
rileya@google.com61348d12012-09-06 13:38:53 +000084 fName.append("rtree_");
85 fName.append(name);
86 fName.append("_query");
87 if (fBulkLoad) {
88 fName.append("_bulk");
89 }
rileya@google.com981b33a2012-09-05 18:36:17 +000090 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +000091
92 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
93 return backend == kNonRendering_Backend;
94 }
95
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +000096 virtual ~RTreeQueryBench() {
rileya@google.com48134582012-09-11 15:41:50 +000097 fTree->unref();
robertphillips@google.com07a05d52012-09-11 11:54:07 +000098 }
rileya@google.com981b33a2012-09-05 18:36:17 +000099protected:
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +0000100 virtual const char* onGetName() SK_OVERRIDE {
rileya@google.com61348d12012-09-06 13:38:53 +0000101 return fName.c_str();
rileya@google.com981b33a2012-09-05 18:36:17 +0000102 }
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +0000103 virtual void onPreDraw() SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000104 SkRandom rand;
mtklein@google.comc2897432013-09-10 19:23:38 +0000105 for (int j = 0; j < NUM_QUERY_RECTS; ++j) {
mtklein6bd41962014-10-02 07:41:56 -0700106 fTree->insert(j, fProc(rand, j, NUM_QUERY_RECTS), fBulkLoad);
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +0000107 }
108 fTree->flushDeferredInserts();
109 }
110
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000111 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000112 SkRandom rand;
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000113 for (int i = 0; i < loops; ++i) {
mtklein6bd41962014-10-02 07:41:56 -0700114 SkTDArray<unsigned> hits;
mtklein533eb782014-08-27 10:39:42 -0700115 SkRect query;
rileya@google.com981b33a2012-09-05 18:36:17 +0000116 switch(fQuery) {
117 case kSmall_QueryType:
mtklein533eb782014-08-27 10:39:42 -0700118 query.fLeft = rand.nextRangeF(0, GENERATE_EXTENTS);
119 query.fTop = rand.nextRangeF(0, GENERATE_EXTENTS);
120 query.fRight = query.fLeft + (GENERATE_EXTENTS / 20);
121 query.fBottom = query.fTop + (GENERATE_EXTENTS / 20);
rileya@google.com981b33a2012-09-05 18:36:17 +0000122 break;
123 case kLarge_QueryType:
mtklein533eb782014-08-27 10:39:42 -0700124 query.fLeft = rand.nextRangeF(0, GENERATE_EXTENTS);
125 query.fTop = rand.nextRangeF(0, GENERATE_EXTENTS);
126 query.fRight = query.fLeft + (GENERATE_EXTENTS / 2);
127 query.fBottom = query.fTop + (GENERATE_EXTENTS / 2);
rileya@google.com981b33a2012-09-05 18:36:17 +0000128 break;
129 case kFull_QueryType:
mtklein533eb782014-08-27 10:39:42 -0700130 query.fLeft = -GENERATE_EXTENTS;
131 query.fTop = -GENERATE_EXTENTS;
132 query.fRight = 2 * GENERATE_EXTENTS;
rileya@google.com981b33a2012-09-05 18:36:17 +0000133 query.fBottom = 2 * GENERATE_EXTENTS;
134 break;
135 default: // fallthrough
136 case kRandom_QueryType:
mtklein533eb782014-08-27 10:39:42 -0700137 query.fLeft = rand.nextRangeF(0, GENERATE_EXTENTS);
138 query.fTop = rand.nextRangeF(0, GENERATE_EXTENTS);
139 query.fRight = query.fLeft + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/2);
140 query.fBottom = query.fTop + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/2);
rileya@google.com981b33a2012-09-05 18:36:17 +0000141 break;
142 };
143 fTree->search(query, &hits);
144 }
145 }
146private:
147 SkBBoxHierarchy* fTree;
148 MakeRectProc fProc;
rileya@google.com61348d12012-09-06 13:38:53 +0000149 SkString fName;
rileya@google.com981b33a2012-09-05 18:36:17 +0000150 bool fBulkLoad;
151 QueryType fQuery;
tfarinaf168b862014-06-19 12:32:29 -0700152 typedef Benchmark INHERITED;
rileya@google.com981b33a2012-09-05 18:36:17 +0000153};
154
mtklein533eb782014-08-27 10:39:42 -0700155static inline SkRect make_concentric_rects_increasing(SkRandom&, int index, int numRects) {
156 SkRect out = SkRect::MakeWH(SkIntToScalar(index+1), SkIntToScalar(index+1));
rileya@google.com981b33a2012-09-05 18:36:17 +0000157 return out;
158}
159
mtklein533eb782014-08-27 10:39:42 -0700160static inline SkRect make_XYordered_rects(SkRandom& rand, int index, int numRects) {
161 SkRect out;
162 out.fLeft = SkIntToScalar(index % GRID_WIDTH);
163 out.fTop = SkIntToScalar(index / GRID_WIDTH);
164 out.fRight = out.fLeft + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/3);
165 out.fBottom = out.fTop + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/3);
sglez@google.com8c902122013-08-30 17:27:47 +0000166 return out;
167}
mtklein533eb782014-08-27 10:39:42 -0700168static inline SkRect make_YXordered_rects(SkRandom& rand, int index, int numRects) {
169 SkRect out;
170 out.fLeft = SkIntToScalar(index / GRID_WIDTH);
171 out.fTop = SkIntToScalar(index % GRID_WIDTH);
172 out.fRight = out.fLeft + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/3);
173 out.fBottom = out.fTop + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/3);
sglez@google.com8c902122013-08-30 17:27:47 +0000174 return out;
175}
176
mtklein533eb782014-08-27 10:39:42 -0700177static inline SkRect make_random_rects(SkRandom& rand, int index, int numRects) {
178 SkRect out;
179 out.fLeft = rand.nextRangeF(0, GENERATE_EXTENTS);
180 out.fTop = rand.nextRangeF(0, GENERATE_EXTENTS);
181 out.fRight = out.fLeft + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/5);
182 out.fBottom = out.fTop + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/5);
rileya@google.com981b33a2012-09-05 18:36:17 +0000183 return out;
184}
185
rileya@google.com981b33a2012-09-05 18:36:17 +0000186///////////////////////////////////////////////////////////////////////////////
187
mtklein@google.com410e6e82013-09-13 19:52:27 +0000188DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000189 return SkNEW_ARGS(RTreeBuildBench, ("XYordered", &make_XYordered_rects, false,
rileya@google.com981b33a2012-09-05 18:36:17 +0000190 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000191)
192DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000193 return SkNEW_ARGS(RTreeBuildBench, ("XYordered", &make_XYordered_rects, true,
rileya@google.com981b33a2012-09-05 18:36:17 +0000194 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000195)
196DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000197 return SkNEW_ARGS(RTreeBuildBench, ("(unsorted)XYordered", &make_XYordered_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000198 SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000199)
200DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000201 return SkNEW_ARGS(RTreeQueryBench, ("XYordered", &make_XYordered_rects, true,
202 RTreeQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000203)
204DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000205 return SkNEW_ARGS(RTreeQueryBench, ("(unsorted)XYordered", &make_XYordered_rects, true,
206 RTreeQueryBench::kRandom_QueryType, SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000207)
rileya@google.com981b33a2012-09-05 18:36:17 +0000208
mtklein@google.com410e6e82013-09-13 19:52:27 +0000209DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000210 return SkNEW_ARGS(RTreeBuildBench, ("YXordered", &make_YXordered_rects, false,
sglez@google.com8c902122013-08-30 17:27:47 +0000211 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000212)
213DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000214 return SkNEW_ARGS(RTreeBuildBench, ("YXordered", &make_YXordered_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000215 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000216)
217DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000218 return SkNEW_ARGS(RTreeBuildBench, ("(unsorted)YXordered", &make_YXordered_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000219 SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000220)
221DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000222 return SkNEW_ARGS(RTreeQueryBench, ("YXordered", &make_YXordered_rects, true,
223 RTreeQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000224)
225DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000226 return SkNEW_ARGS(RTreeQueryBench, ("(unsorted)YXordered", &make_YXordered_rects, true,
227 RTreeQueryBench::kRandom_QueryType, SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000228)
sglez@google.com8c902122013-08-30 17:27:47 +0000229
mtklein@google.com410e6e82013-09-13 19:52:27 +0000230DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000231 return SkNEW_ARGS(RTreeBuildBench, ("random", &make_random_rects, false,
sglez@google.com8c902122013-08-30 17:27:47 +0000232 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000233)
234DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000235 return SkNEW_ARGS(RTreeBuildBench, ("random", &make_random_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000236 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000237)
238DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000239 return SkNEW_ARGS(RTreeBuildBench, ("(unsorted)random", &make_random_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000240 SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000241)
242DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000243 return SkNEW_ARGS(RTreeQueryBench, ("random", &make_random_rects, true,
244 RTreeQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000245)
246DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000247 return SkNEW_ARGS(RTreeQueryBench, ("(unsorted)random", &make_random_rects, true,
248 RTreeQueryBench::kRandom_QueryType, SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000249)
sglez@google.com8c902122013-08-30 17:27:47 +0000250
mtklein@google.com410e6e82013-09-13 19:52:27 +0000251DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000252 return SkNEW_ARGS(RTreeBuildBench, ("concentric",
sglez@google.com8c902122013-08-30 17:27:47 +0000253 &make_concentric_rects_increasing, true, SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000254)
255DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000256 return SkNEW_ARGS(RTreeBuildBench, ("(unsorted)concentric",
sglez@google.com8c902122013-08-30 17:27:47 +0000257 &make_concentric_rects_increasing, true, SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000258)
259DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000260 return SkNEW_ARGS(RTreeQueryBench, ("concentric", &make_concentric_rects_increasing, true,
261 RTreeQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000262)
263DEF_BENCH(
commit-bot@chromium.orgb2db4432014-04-23 21:03:45 +0000264 return SkNEW_ARGS(RTreeQueryBench, ("(unsorted)concentric", &make_concentric_rects_increasing, true,
265 RTreeQueryBench::kRandom_QueryType, SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000266)