diff --git a/bench/QuadTreeBench.cpp b/bench/QuadTreeBench.cpp
new file mode 100644
index 0000000..f1d5bcf
--- /dev/null
+++ b/bench/QuadTreeBench.cpp
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkBenchmark.h"
+#include "SkCanvas.h"
+#include "SkQuadTree.h"
+#include "SkRandom.h"
+#include "SkString.h"
+
+// confine rectangles to a smallish area, so queries generally hit something, and overlap occurs:
+static const int GENERATE_EXTENTS = 1000;
+static const int NUM_BUILD_RECTS = 500;
+static const int NUM_QUERY_RECTS = 5000;
+static const int GRID_WIDTH = 100;
+static const SkIRect QUAD_TREE_BOUNDS = SkIRect::MakeLTRB(
+    -GENERATE_EXTENTS, -GENERATE_EXTENTS, 2 * GENERATE_EXTENTS, 2 * GENERATE_EXTENTS);
+
+typedef SkIRect (*MakeRectProc)(SkRandom&, int, int);
+
+// Time how long it takes to build an QuadTree
+class BBoxBuildBench : public SkBenchmark {
+public:
+    BBoxBuildBench(const char* name, MakeRectProc proc, SkBBoxHierarchy* tree)
+        : fTree(tree)
+        , fProc(proc) {
+        fName.append("quadtree_");
+        fName.append(name);
+        fName.append("_build");
+    }
+
+    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
+        return backend == kNonRendering_Backend;
+    }
+
+    virtual ~BBoxBuildBench() {
+        fTree->unref();
+    }
+protected:
+    virtual const char* onGetName() SK_OVERRIDE {
+        return fName.c_str();
+    }
+    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
+        SkRandom rand;
+        for (int i = 0; i < loops; ++i) {
+            for (int j = 0; j < NUM_BUILD_RECTS; ++j) {
+                fTree->insert(reinterpret_cast<void*>(j), fProc(rand, j, NUM_BUILD_RECTS),
+                              false);
+            }
+            fTree->clear();
+        }
+    }
+private:
+    SkBBoxHierarchy* fTree;
+    MakeRectProc fProc;
+    SkString fName;
+    typedef SkBenchmark INHERITED;
+};
+
+// Time how long it takes to perform queries on an QuadTree
+class BBoxQueryBench : public SkBenchmark {
+public:
+    enum QueryType {
+        kSmall_QueryType, // small queries
+        kLarge_QueryType, // large queries
+        kRandom_QueryType,// randomly sized queries
+        kFull_QueryType   // queries that cover everything
+    };
+
+    BBoxQueryBench(const char* name, MakeRectProc proc,
+                    QueryType q, SkBBoxHierarchy* tree)
+        : fTree(tree)
+        , fProc(proc)
+        , fQuery(q) {
+        fName.append("quadtree_");
+        fName.append(name);
+        fName.append("_query");
+    }
+
+    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
+        return backend == kNonRendering_Backend;
+    }
+
+    virtual ~BBoxQueryBench() {
+        fTree->unref();
+    }
+protected:
+    virtual const char* onGetName() SK_OVERRIDE {
+        return fName.c_str();
+    }
+    virtual void onPreDraw() SK_OVERRIDE {
+        SkRandom rand;
+        for (int j = 0; j < NUM_QUERY_RECTS; ++j) {
+            fTree->insert(reinterpret_cast<void*>(j),
+                          fProc(rand, j, NUM_QUERY_RECTS),
+                          false);
+        }
+        fTree->flushDeferredInserts();
+    }
+
+    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
+        SkRandom rand;
+        for (int i = 0; i < loops; ++i) {
+            SkTDArray<void*> hits;
+            SkIRect query;
+            switch(fQuery) {
+                case kSmall_QueryType:
+                    query.fLeft = rand.nextU() % GENERATE_EXTENTS;
+                    query.fTop = rand.nextU() % GENERATE_EXTENTS;
+                    query.fRight = query.fLeft + (GENERATE_EXTENTS / 20);
+                    query.fBottom = query.fTop + (GENERATE_EXTENTS / 20);
+                    break;
+                case kLarge_QueryType:
+                    query.fLeft = rand.nextU() % GENERATE_EXTENTS;
+                    query.fTop = rand.nextU() % GENERATE_EXTENTS;
+                    query.fRight = query.fLeft + (GENERATE_EXTENTS / 2);
+                    query.fBottom = query.fTop + (GENERATE_EXTENTS / 2);
+                    break;
+                case kFull_QueryType:
+                    query.fLeft = -GENERATE_EXTENTS;
+                    query.fTop = -GENERATE_EXTENTS;
+                    query.fRight = 2 * GENERATE_EXTENTS;
+                    query.fBottom = 2 * GENERATE_EXTENTS;
+                    break;
+                default: // fallthrough
+                case kRandom_QueryType:
+                    query.fLeft = rand.nextU() % GENERATE_EXTENTS;
+                    query.fTop = rand.nextU() % GENERATE_EXTENTS;
+                    query.fRight = query.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 2);
+                    query.fBottom = query.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 2);
+                    break;
+            };
+            fTree->search(query, &hits);
+        }
+    }
+private:
+    SkBBoxHierarchy* fTree;
+    MakeRectProc fProc;
+    SkString fName;
+    QueryType fQuery;
+    typedef SkBenchmark INHERITED;
+};
+
+static inline SkIRect make_concentric_rects_increasing(SkRandom&, int index, int numRects) {
+    SkIRect out = {0, 0, index + 1, index + 1};
+    return out;
+}
+
+static inline SkIRect make_XYordered_rects(SkRandom& rand, int index, int numRects) {
+    SkIRect out;
+    out.fLeft = index % GRID_WIDTH;
+    out.fTop = index / GRID_WIDTH;
+    out.fRight  = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
+    out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
+    return out;
+}
+
+static inline SkIRect make_YXordered_rects(SkRandom& rand, int index, int numRects) {
+    SkIRect out;
+    out.fLeft = index / GRID_WIDTH;
+    out.fTop = index % GRID_WIDTH;
+    out.fRight  = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
+    out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
+    return out;
+}
+
+static inline SkIRect make_random_rects(SkRandom& rand, int index, int numRects) {
+    SkIRect out;
+    out.fLeft   = rand.nextS() % GENERATE_EXTENTS;
+    out.fTop    = rand.nextS() % GENERATE_EXTENTS;
+    out.fRight  = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 5);
+    out.fBottom = out.fTop  + 1 + rand.nextU() % (GENERATE_EXTENTS / 5);
+    return out;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+DEF_BENCH(
+    return SkNEW_ARGS(BBoxBuildBench, ("XYordered", &make_XYordered_rects,
+                      SkQuadTree::Create(QUAD_TREE_BOUNDS)));
+)
+DEF_BENCH(
+    return SkNEW_ARGS(BBoxQueryBench, ("XYordered", &make_XYordered_rects,
+                      BBoxQueryBench::kRandom_QueryType, SkQuadTree::Create(QUAD_TREE_BOUNDS)));
+)
+DEF_BENCH(
+    return SkNEW_ARGS(BBoxBuildBench, ("YXordered", &make_YXordered_rects,
+                      SkQuadTree::Create(QUAD_TREE_BOUNDS)));
+)
+DEF_BENCH(
+    return SkNEW_ARGS(BBoxQueryBench, ("YXordered", &make_YXordered_rects,
+                      BBoxQueryBench::kRandom_QueryType, SkQuadTree::Create(QUAD_TREE_BOUNDS)));
+)
+DEF_BENCH(
+    return SkNEW_ARGS(BBoxBuildBench, ("random", &make_random_rects,
+                      SkQuadTree::Create(QUAD_TREE_BOUNDS)));
+)
+DEF_BENCH(
+    return SkNEW_ARGS(BBoxQueryBench, ("random", &make_random_rects,
+                      BBoxQueryBench::kRandom_QueryType, SkQuadTree::Create(QUAD_TREE_BOUNDS)));
+)
+DEF_BENCH(
+    return SkNEW_ARGS(BBoxBuildBench, ("concentric", &make_concentric_rects_increasing,
+                      SkQuadTree::Create(QUAD_TREE_BOUNDS)));
+)
+DEF_BENCH(
+    return SkNEW_ARGS(BBoxQueryBench, ("concentric", &make_concentric_rects_increasing,
+                      BBoxQueryBench::kRandom_QueryType, SkQuadTree::Create(QUAD_TREE_BOUNDS)));
+)
