Performance of removing rprim from RenderIndex

Hi everyone,

I’m coming across a performance issue in HdRenderIndex::RemoveRprim related to HD_ENABLE_SCENE_INDEX_EMULATION on MacOS. Compared with NO emulation, RemoveRprim could be significantly slow especially when removing amount goes to 10k+.

The bottleneck is in SdfPathTable (to be more precious, _Entry::RemoveChild). As this is a very fundamental data structure, this issue could impact many other modules.

Following is a simple way to reproduce this problem with RenderIndex:

const int testAmount = 1 << 16;
const std::string prefix = isFlattened ? "/prim_" : "/root/prim_";
SdfPathVector pathList;

// Prepare data set.
for (int i = 0; i < testAmount; ++i)
    SdfPath id(prefix + std::to_string(i));
    pRenderIndex->InsertRprim(HdPrimTypeTokens->mesh, pSceneDelegate, id);
pRenderIndex->SyncAll(&tasks, &taskContext);

// Timing block
    for (int i = 0; i < testAmount; ++i)

pRenderIndex->SyncAll(&tasks, &taskContext);

Either with parent node or not could notice this problem. And this is the comparison results with google benchmark (mean of 9 iter) on Mac M2 (4p core + 4e core, 24G mem):

Benchmark(FixtureName/CaseName/testAmount/isFlattened)              Ratio    Without Simulation(ns)    With Simulation(ns)
HydraFixture/TestRenderIndexRemoval/8/0_mean                      +0.7676                      4432                   7835
HydraFixture/TestRenderIndexRemoval/64/0_mean                     +1.0302                     36036                  73160
HydraFixture/TestRenderIndexRemoval/512/0_mean                    +3.5271                    222733                1008337
HydraFixture/TestRenderIndexRemoval/4096/0_mean                  +18.2766                   2553746               49227664
HydraFixture/TestRenderIndexRemoval/32768/0_mean                 +30.6114                  81251933             2568485579
HydraFixture/TestRenderIndexRemoval/65536/0_mean                 +46.4456                 235663733            11181215722
HydraFixture/TestRenderIndexRemoval/8/1_mean                      +0.7398                      4527                   7877
HydraFixture/TestRenderIndexRemoval/64/1_mean                     +0.9724                     37361                  73691
HydraFixture/TestRenderIndexRemoval/512/1_mean                    +3.6652                    220050                1026568
HydraFixture/TestRenderIndexRemoval/4096/1_mean                  +18.7637                   2505614               49520191
HydraFixture/TestRenderIndexRemoval/32768/1_mean                 +31.1191                  80429033             2583304667
HydraFixture/TestRenderIndexRemoval/65536/1_mean                 +46.6312                 236563287            11267796458

Does anyone have any idea? That would be really helpful!

Thank you,
Lumina Wang

Hi Lumina,

The best practice for removing prims in HdRenderIndex is either to call HdRenderIndex::Clear (which is quite fast, but removes everything); or HdRenderIndex::RemoveSubtree(“/path”, &sceneDelegate), which can remove everything under a specific prefix inserted by a specific scene delegate. Doing bulk removal by calling RemoveRprim isn’t recommended, as the batched APIs give us much more room to optimize.

Is it possible for you to use either of those two functions? And do they have better performance characteristics in your case?


Hi Tom,

Thank you for your suggestions! RemoveSubtree can do better if the scene is pretty well organized. However, it still has problems when the tree is quite flattened. Fortunately, we (Autodesk) have investigated and made some improvements. We’d also like to contribute them to OpenUSD as these changes could benefit various users.

Thank you,

I’m glad to hear you’ve found a solution, and excited to see it as a contribution! Our PR process is laid out here: Contributing to USD — Universal Scene Description 24.02 documentation