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 entries3 (0.258s)6 (0.154s)2 (0.386s)3 (0.297s)
Elements In Range
Elements In Range KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (~span/2) (r=49.50)20232914
Half (~span/4) (r=24.75)151166164116
Quarter (~span/8) (r=12.38)1,0241,2601,5501,286
Tiny (~span/1000) (r=1)23,62722,558130,69672,437
Get Elements In Bounds
Get Elements In Bounds KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (size≈99.00x99.00x99.00)303517220
Half (size≈49.50x49.50x49.50)40481,270218
Quarter (size≈24.75x24.75x24.75)40513,6012,338
Unit (size=1)4253161,97970,789
Approximate Nearest Neighbors
Approximate Nearest Neighbors KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
500 neighbors6,07110,4252,251301
100 neighbors63,99671,93910,4303,189
10 neighbors295,220302,02015,1486,980
1 neighbor326,786340,47918,3257,588

100,000 entries

Construction
Construction KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
100,000 entries49 (0.020s)97 (0.010s)63 (0.016s)8 (0.120s)
Elements In Range
Elements In Range KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (~span/2) (r=49.50)381592769176
Half (~span/4) (r=24.75)1,1351,6501,860727
Quarter (~span/8) (r=12.38)2,8144,4995,9463,021
Tiny (~span/1000) (r=1)26,91030,212163,64093,042
Get Elements In Bounds
Get Elements In Bounds KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (size≈99.00x99.00x9)5976883,044352
Half (size≈49.50x49.50x4.5)6748508,8583,459
Quarter (size≈24.75x24.75x2.25)71087042,33423,513
Unit (size=1)728880208,36292,740
Approximate Nearest Neighbors
Approximate Nearest Neighbors KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
500 neighbors6,82612,3991,582266
100 neighbors39,10244,9328,7012,065
10 neighbors320,222258,26118,0616,748
1 neighbor329,497259,58327,85910,618

10,000 entries

Construction
Construction KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
10,000 entries232 (0.004s)776 (0.001s)599 (0.002s)435 (0.002s)
Elements In Range
Elements In Range KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (~span/2) (r=49.50)5,0105,0799,1391,721
Half (~span/4) (r=24.75)6,2507,0218,4933,453
Quarter (~span/8) (r=12.38)6,3367,32610,6776,600
Tiny (~span/1000) (r=1)42,21338,535199,646142,424
Get Elements In Bounds
Get Elements In Bounds KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (size≈99.00x9x9)6,1586,04031,5753,564
Half (size≈49.50x4.5x4.5)6,8626,78441,74136,487
Quarter (size≈24.75x2.25x2.25)7,0357,114147,595111,575
Unit (size=1)6,8577,135273,980147,480
Approximate Nearest Neighbors
Approximate Nearest Neighbors KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
500 neighbors9,99010,905633181
100 neighbors49,03367,7255,9282,087
10 neighbors222,009313,53025,97811,079
1 neighbor352,912395,31642,06018,631

1,000 entries

Construction
Construction KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
1,000 entries5,047 (0.000s)7,017 (0.000s)4,221 (0.000s)4,056 (0.000s)
Elements In Range
Elements In Range KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (~span/2) (r=4.5)13,30915,40724,55519,376
Half (~span/4) (r=2.25)54,63164,832119,069122,189
Quarter (~span/8) (r=1.13)63,80966,230302,733190,679
Tiny (~span/1000) (r=1)63,92566,775297,025189,076
Get Elements In Bounds
Get Elements In Bounds KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (size≈9x9x9)56,02560,364285,85134,830
Half (size≈4.5x4.5x4.5)60,43565,721167,043160,053
Quarter (size≈2.25x2.25x2.25)60,89267,241408,947203,923
Unit (size=1)60,85966,633408,812205,130
Approximate Nearest Neighbors
Approximate Nearest Neighbors KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
500 neighbors15,07915,2213,229617
100 neighbors66,51765,35415,3723,961
10 neighbors326,664303,34469,25927,619
1 neighbor372,951425,92178,02135,781

100 entries

Construction
Construction KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
100 entries38,461 (0.000s)36,496 (0.000s)26,178 (0.000s)18,552 (0.000s)
Elements In Range
Elements In Range KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (~span/2) (r=4.5)128,838126,647268,664156,643
Half (~span/4) (r=2.25)132,912157,069283,144241,941
Quarter (~span/8) (r=1.13)155,589157,614341,201328,411
Tiny (~span/1000) (r=1)156,184155,346349,424328,728
Get Elements In Bounds
Get Elements In Bounds KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (size≈9x4x1)444,834441,3951,132,436267,317
Half (size≈4.5x2x1)458,537464,441413,889347,753
Quarter (size≈2.25x1x1)468,261464,503578,248476,261
Unit (size=1)469,295459,734573,732477,462
Approximate Nearest Neighbors
Approximate Nearest Neighbors KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
100 neighbors (max)87,62281,75860,94457,383
10 neighbors381,364355,35093,40174,007
1 neighbor439,990402,016146,308149,981

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