ikpil / DotRecast

DotRecast - a port of Recast & Detour, Industry-standard navigation mesh toolset for .NET, C#, Unity3D, games, servers
zlib License
563 stars 72 forks source link

DotRecast creating a lot of RcSpan objects for a relatively small scene. #66

Closed bryanedds closed 6 months ago

bryanedds commented 7 months ago

I'm in the memory profiler today checking in on my program and was surprised by the number of objects that DotRecast is creating and keeping live for what might be considered a relatively small scene -

image

Here you'll notice we have 500k live instances of RcSpan -

image

Is there any change we can make to DotRecast or our usage to reduce the object count footprint here? Maybe a different internal representation or perhaps a posteri pruning? Or perhaps there's a reference from the mesh construction process I can let go of? I currently keep a reference to RcBuilderResult so I can draw the above debug lines. Should I not hold on to that? If so, would there be a better way to draw debug info for the nav mesh than using RcBuilderResult? If not, can I prune RcBuilderResult somehow?

Since we're dealing with realtime games, we'd like to keep the GC sweep phase as cheap as possible.

Lastly, here's the related issue I filed locally -

https://github.com/bryanedds/Nu/issues/774

Thank you for your greatly helpful project - it has already saved us tremendous amounts of time and effort!

ikpil commented 7 months ago

Hello, We're currently working on the issues you mentioned.

The problem seems to stem from RcBuilderResult referencing many objects. We're currently working on optimizing RcSpan. Once the issue is resolved, we will mention it.

bryanedds commented 7 months ago

Thank you kindly!

ikpil commented 6 months ago

@bryanedds 50ea674 - used option keepInterResults to save memory

Inspired by the recastnavigation source code, I added the keepInterResults option. You will be able to see that it significantly reduces memory usage.

bryanedds commented 6 months ago

I don't think this change set helps us because none of the changes touch our actual use path. Here's how we use DotRecast currently -

https://github.com/bryanedds/Nu/blob/70edd89adab2e2befab54ceba4cfb370354c2453/Nu/Nu/World/WorldScreen.fs#L453-L467

We use the public RcBuilderResult Build(IInputGeomProvider geom, RcBuilderConfig bcfg) method to generate our nav data, which in turn calls public RcBuilderResult Build(RcContext ctx, int tileX, int tileZ, IInputGeomProvider geom, RcConfig cfg, RcHeightfield solid). As far as I can see, neither of those code paths are hit any of the code you changed.

Am I missing something?

ikpil commented 6 months ago

@bryanedds

9777751 - Added the keepInterResults option to RcBuilder.Build()

fixed!!

bryanedds commented 6 months ago

Thank you, this should work better!