Skip to content

3D Spatial Tree Performance Benchmarks

TL;DR: What Problem This Solves

  • Need fast “what’s near X?” or “what’s inside this volume?” in 3D.
  • These structures avoid scanning every object; queries touch only nearby data.
  • Quick picks: OctTree3D for general 3D queries; KdTree3D for nearest‑neighbor on points; RTree3D for volumetric bounds.

Note: KdTree3D, OctTree3D, and RTree3D are under active development and their APIs/performance may evolve. SpatialHash3D is stable and recommended for broad‑phase neighbor queries with many moving objects.

For boundary and result semantics across structures, see Spatial Tree Semantics

This document contains performance benchmarks for the 3D spatial tree implementations in Unity Helpers.

Available 3D Spatial Trees

  • OctTree3D - Easiest to use, good all-around performance for 3D
  • KdTree3D - Balanced and unbalanced variants available
  • RTree3D - Optimized for 3D bounding box queries
  • SpatialHash3D - Efficient for uniformly distributed moving objects (stable)

Performance Benchmarks

Datasets

1,000,000 entries

Construction
Construction KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
1,000,000 entries2 (0.340s)5 (0.193s)2 (0.443s)1 (0.560s)
Elements In Range
Elements In Range KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (~span/2) (r=49.50)30333214
Half (~span/4) (r=24.75)258288251161
Quarter (~span/8) (r=12.38)1,8782,2741,7471,567
Tiny (~span/1000) (r=1)68,46768,902140,37170,584
Get Elements In Bounds
Get Elements In Bounds KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (size≈99.00x99.00x99.00)323519718
Half (size≈49.50x49.50x49.50)44491,121279
Quarter (size≈24.75x24.75x24.75)45523,2492,901
Unit (size=1)4853146,79772,976
Approximate Nearest Neighbors
Approximate Nearest Neighbors KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
500 neighbors14,95231,2122,5591,285
100 neighbors158,435175,62312,7336,641
10 neighbors488,977323,35318,7269,150
1 neighbor555,407278,32722,9219,414

100,000 entries

Construction
Construction KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
100,000 entries42 (0.024s)80 (0.012s)56 (0.018s)27 (0.036s)
Elements In Range
Elements In Range KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (~span/2) (r=49.50)412489642213
Half (~span/4) (r=24.75)1,4641,8761,920836
Quarter (~span/8) (r=12.38)4,7467,0006,3043,454
Tiny (~span/1000) (r=1)74,64083,016182,42494,286
Get Elements In Bounds
Get Elements In Bounds KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (size≈99.00x99.00x9)5877262,580399
Half (size≈49.50x49.50x4.5)6738478,0024,047
Quarter (size≈24.75x24.75x2.25)68385538,89827,884
Unit (size=1)706836190,11696,833
Approximate Nearest Neighbors
Approximate Nearest Neighbors KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
500 neighbors22,84237,7901,8261,170
100 neighbors111,561118,52910,5954,356
10 neighbors548,563443,95422,8558,878
1 neighbor553,853392,85135,43113,695

10,000 entries

Construction
Construction KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
10,000 entries519 (0.002s)596 (0.002s)545 (0.002s)320 (0.003s)
Elements In Range
Elements In Range KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (~span/2) (r=49.50)4,2954,3166,1922,171
Half (~span/4) (r=24.75)7,3717,9007,9994,246
Quarter (~span/8) (r=12.38)10,44112,00312,6267,274
Tiny (~span/1000) (r=1)116,107110,829240,202143,509
Get Elements In Bounds
Get Elements In Bounds KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (size≈99.00x9x9)6,0215,94124,7154,112
Half (size≈49.50x4.5x4.5)6,8896,76037,84742,414
Quarter (size≈24.75x2.25x2.25)6,8696,894136,372118,433
Unit (size=1)6,9447,020261,198148,865
Approximate Nearest Neighbors
Approximate Nearest Neighbors KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
500 neighbors28,06229,396638858
100 neighbors130,380170,9686,9265,238
10 neighbors494,527428,41635,43216,135
1 neighbor608,641604,54555,46025,402

1,000 entries

Construction
Construction KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
1,000 entries4,191 (0.000s)5,927 (0.000s)3,631 (0.000s)3,231 (0.000s)
Elements In Range
Elements In Range KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (~span/2) (r=4.5)28,24731,77729,00922,421
Half (~span/4) (r=2.25)141,701167,956149,245138,145
Quarter (~span/8) (r=1.13)171,864177,662358,881199,969
Tiny (~span/1000) (r=1)171,026175,651358,054197,144
Get Elements In Bounds
Get Elements In Bounds KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (size≈9x9x9)55,36760,588231,92442,034
Half (size≈4.5x4.5x4.5)60,82664,675158,172166,422
Quarter (size≈2.25x2.25x2.25)59,88165,929383,738208,592
Unit (size=1)61,34067,222383,240209,228
Approximate Nearest Neighbors
Approximate Nearest Neighbors KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
500 neighbors34,91537,9523,4992,843
100 neighbors153,489165,61218,69713,630
10 neighbors536,964398,35793,47044,258
1 neighbor640,037650,403104,00355,357

100 entries

Construction
Construction KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
100 entries38,759 (0.000s)10,030 (0.000s)24,213 (0.000s)15,698 (0.000s)
Elements In Range
Elements In Range KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (~span/2) (r=4.5)266,801266,250302,534192,410
Half (~span/4) (r=2.25)341,789349,460356,948281,973
Quarter (~span/8) (r=1.13)346,927326,452425,838359,988
Tiny (~span/1000) (r=1)340,885355,813433,093358,502
Get Elements In Bounds
Get Elements In Bounds KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (size≈9x4x1)479,348475,5421,205,263322,799
Half (size≈4.5x2x1)491,498501,104391,708381,900
Quarter (size≈2.25x1x1)498,882495,579549,227536,053
Unit (size=1)491,599486,230548,382528,585
Approximate Nearest Neighbors
Approximate Nearest Neighbors KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
100 neighbors (max)192,205196,614109,799155,845
10 neighbors615,894563,599139,741217,289
1 neighbor625,397641,929212,152352,882

Interpreting the Results

All numbers represent operations per second (higher is better), except for construction times which show operations per second and absolute time.

Choosing the Right Tree

OctTree3D:

  • Best for: General-purpose 3D spatial queries
  • Strengths: Balanced performance, easy to use, good spatial locality
  • Use cases: 3D collision detection, visibility culling, spatial audio

KdTree3D (Balanced):

  • Best for: Nearest-neighbor queries in 3D space
  • Strengths: Fast point queries, good for smaller datasets
  • Use cases: Pathfinding, AI spatial awareness, particle systems

KdTree3D (Unbalanced):

  • Best for: When you need fast construction and will rebuild frequently
  • Strengths: Fastest construction, similar query performance to balanced
  • Use cases: Dynamic environments, frequently changing spatial data

RTree3D:

  • Best for: 3D bounding box queries, especially with volumetric data
  • Strengths: Excellent for large bounding volumes, handles overlapping objects
  • Use cases: Physics engines, frustum culling, volumetric effects

Important Notes

  • All spatial trees assume immutable positional data
  • If positions change, you must reconstruct the tree
  • Spatial queries are O(log n) vs O(n) for linear search
  • 3D trees have higher construction costs than 2D variants due to additional dimension
  • Construction cost is amortized over many queries