I've spent some time investigating the pretty big memory usage of
ItemTrees today, and tried to optimize the
ItemTree representation, but without much success. I collected some data via
analysis-bench --memory-usage --highlight src/lib.rs in the rust-analyzer crate:
ItemTrees from real source files, totaling in at 77mb
Option<Box<Map>>only saves 2mb of memory
Option<Box<Map>>has no visible impact on memory usage
To help with the latter point, I tried storing all items in a shared arena by converting everything that's stored in the tree to an enum, but this initially just used even more memory due to the enum being as large as the largest contained type. I then used
Boxes inside the enum, which helped a bit, but still saved almost nothing.
I think to improve the memory efficiency here we need to do some larger-scale changes. Maybe we need to avoid creating so many small macro-derived item trees in the first place, by side-stepping the item tree in the right places – I briefly chatted with @matklad about this. I'm not sure where these "right places" are though, is the def collector alone enough? And how do we reduce the memory used by non-macro trees? Rely on periodic GC to clean them up? Open for ideas here :)
One idea I had is to have a global arena for items
I don't think we can implement it without salsa, but it might be a good idea to prototype, to get a rough memory usage
Like, literarrly just sticking an
Arc<Mutext(Arena<Struct>, Arena<Enum>, ...)> into a DB, and store only
That should be horribly slow, but should give us a fair assesment of overhead of many arenas
It also seems that ItemTrees, while being the heaviset thing, are still just 15% of overall memory usage...
I wonder if that means that some wide-reaching optimizations are more important, like interning of names
Quite possible, yeah
Maybe that is a good next thing to look into - how much memory is actually occupied by names?
Just did a quick check, making
Name twice as bit leads to +120mb of memory
Okay, that seems promising!