Skip to content

Latest commit

 

History

History
462 lines (393 loc) · 20.3 KB

File metadata and controls

462 lines (393 loc) · 20.3 KB

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.262s)6 (0.153s)2 (0.352s)3 (0.294s)
Elements In Range
Elements In Range KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (~span/2) (r=49.50)20243317
Half (~span/4) (r=24.75)152187263169
Quarter (~span/8) (r=12.38)1,0321,3581,6681,502
Tiny (~span/1000) (r=1)23,72523,819133,28271,954
Get Elements In Bounds
Get Elements In Bounds KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (size≈99.00x99.00x99.00)354023324
Half (size≈49.50x49.50x49.50)48561,241278
Quarter (size≈24.75x24.75x24.75)49563,6512,511
Unit (size=1)5152163,17073,047
Approximate Nearest Neighbors
Approximate Nearest Neighbors KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
500 neighbors6,24210,6072,321303
100 neighbors63,30572,46910,8723,283
10 neighbors295,644307,37315,9797,236
1 neighbor336,117352,61919,6618,156

100,000 entries

Construction
Construction KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
100,000 entries13 (0.072s)94 (0.011s)64 (0.016s)44 (0.023s)
Elements In Range
Elements In Range KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (~span/2) (r=49.50)385591774211
Half (~span/4) (r=24.75)1,1411,7321,991838
Quarter (~span/8) (r=12.38)2,8624,7316,0203,407
Tiny (~span/1000) (r=1)27,68131,623167,23694,401
Get Elements In Bounds
Get Elements In Bounds KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (size≈99.00x99.00x9)6247312,794356
Half (size≈49.50x49.50x4.5)7178548,9963,486
Quarter (size≈24.75x24.75x2.25)72787543,44323,687
Unit (size=1)733884211,59994,890
Approximate Nearest Neighbors
Approximate Nearest Neighbors KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
500 neighbors6,94312,5161,654269
100 neighbors39,66045,2529,3162,180
10 neighbors323,237260,28719,0477,206
1 neighbor332,074263,01029,49011,252

10,000 entries

Construction
Construction KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
10,000 entries123 (0.008s)773 (0.001s)597 (0.002s)433 (0.002s)
Elements In Range
Elements In Range KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (~span/2) (r=49.50)4,8875,1069,1732,188
Half (~span/4) (r=24.75)6,2937,0759,0014,230
Quarter (~span/8) (r=12.38)6,2917,45511,1987,437
Tiny (~span/1000) (r=1)41,93339,762207,044143,782
Get Elements In Bounds
Get Elements In Bounds KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (size≈99.00x9x9)6,2446,16528,2643,509
Half (size≈49.50x4.5x4.5)7,0006,98642,23935,660
Quarter (size≈24.75x2.25x2.25)7,1257,161149,019111,164
Unit (size=1)7,2047,177274,570146,522
Approximate Nearest Neighbors
Approximate Nearest Neighbors KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
500 neighbors10,17811,176636185
100 neighbors48,65369,0385,9542,208
10 neighbors228,792322,31926,63212,390
1 neighbor346,732403,63343,79820,882

1,000 entries

Construction
Construction KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
1,000 entries5,027 (0.000s)7,342 (0.000s)4,194 (0.000s)3,855 (0.000s)
Elements In Range
Elements In Range KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (~span/2) (r=4.5)13,21615,83624,52821,168
Half (~span/4) (r=2.25)54,77665,071119,223134,932
Quarter (~span/8) (r=1.13)63,67266,530305,884197,776
Tiny (~span/1000) (r=1)63,66866,291306,143196,875
Get Elements In Bounds
Get Elements In Bounds KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (size≈9x9x9)56,53960,422289,84834,779
Half (size≈4.5x4.5x4.5)59,91765,887172,693158,343
Quarter (size≈2.25x2.25x2.25)60,87467,913408,245202,987
Unit (size=1)60,59468,914408,355202,835
Approximate Nearest Neighbors
Approximate Nearest Neighbors KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
500 neighbors16,59415,5703,265616
100 neighbors69,99166,10315,4624,020
10 neighbors324,837305,60170,30129,522
1 neighbor399,134428,88578,57638,531

100 entries

Construction
Construction KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
100 entries36,363 (0.000s)39,062 (0.000s)28,409 (0.000s)11,389 (0.000s)
Elements In Range
Elements In Range KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (~span/2) (r=4.5)134,264133,125268,794173,242
Half (~span/4) (r=2.25)155,435157,119287,851244,592
Quarter (~span/8) (r=1.13)156,564158,685347,661328,932
Tiny (~span/1000) (r=1)155,612158,148350,184329,295
Get Elements In Bounds
Get Elements In Bounds KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
Full (size≈9x4x1)445,137442,1621,133,386269,238
Half (size≈4.5x2x1)456,470460,381413,163351,246
Quarter (size≈2.25x1x1)470,424465,685581,178493,257
Unit (size=1)469,798465,875578,881473,813
Approximate Nearest Neighbors
Approximate Nearest Neighbors KDTree3D (Balanced) KDTree3D (Unbalanced) OctTree3D RTree3D
100 neighbors (max)87,27685,34763,43765,384
10 neighbors361,756369,20494,88882,476
1 neighbor504,598421,747150,382156,721

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