These are all theoretical without much substance to back it up. The real benefits is not just automatic memory management, it’s the not needing the in memory cache at all. no async code and things being out of sync :

nostr:nevent1qqsqharjpzfpsh85da022j4kds07jdqfkmu99jcwfhrsn4usv6pdzpgpzpmhxue69uhkummnw3ezuamfdejszrthwden5te0dehhxtnvdakqz9thwden5te0wfjkccte9ekk7um5wgh8qatzqyd8wumn8ghj7mn0wd68ytn0wfskuem9wp5kcmpwv3jhvmlf0gf

Reply to this note

Please Login to reply.

Discussion

They are not theorical man... Efficient garbage collection without the dev even thinking about it is literally the whole reason Java exists. Every app uses those things all the time. For many apps, the cache is just the list objects for the feed itself. We do some crazy things on top of it, but I don't expect anyone to have to do it for smaller apps. The rest is just regular loads using Nostr filters.

you’ve chosen to optimize in an area I’m avoiding entirely. I am just happy i don’t have to deal with garbage collection and inefficient use of memory.

You are not avoiding it. You are making an entire DB to mimic garbage collection because you don't have garbage collection. I fell like I am the one avoiding everything you went through to make it.

And I am happy you are doing it. I really do. All I am asking is this discussion is to provide performance indicators that allows us to compare the complete performance with other stacks.

If I compare my cache with your DB already in memory, the performance is exactly the same. Mine might be slower because it is full thread safe for 1000s of reads and writes in the same millisecond. But that's it. Basically its the difference between B+ trees vs hash tables.

So, if I follow 500 people and use 5 Nostr apps, do you truly think duplicating 500 profiles in memory on each of those apps is an "efficient" use of memory?

In your example it is not, but in the notedeck usecase (nostr browser) of potentially hundreds of apps in a single process is very efficient and faster than having in memory caches of duplicate data from a local relay across multiple processes.

And yes if you have something in memory is likely the same or faster when using a hashmap, but performance isn’t a one dimensional thing like comparing btree to hashmap performance. It’s the entire system as a whole. For instance, the binary note format is cpu cache friendly. Even just switching to that in damus ios helped perf immensely.

A lot of the computational things involved in note processing is amortized by having it done up front in the nostrdb and stored forever. Things like note content parsing (contents are chopped up into blocks, these are just offsets into the contents tagged with a type (url, hashtag, etc), stat counting, etc. i’m also going to add and store minimal perfect hashmaps for efficient mute word checking.

Just having these data structures near the note in memory and available to any app without duplicate processing was another motivation.

notedeck is a realtime system, i can’t have it do any work on the render thread. The render path has to be as fast as possible, it has forced me to move all of the computational upfront work into the nostrdb ingester pool.

This results in a smooth scrolling experience because the render thread is just accessing pointers to data that has already been processed.

Anyway, just trying to point out that hyper fixating on one component of the system would be misleading, as it was specifically designed for performance at every level.

If you want to check performance just run notedeck, you will see the results.

Agree, we don't use the render path either. Though I lazy load/compute the additional data structure (like the text parsing) only when the event is being placed in the same page that will be rendered. And those can be discarded individually by the GC after the event is old/not used anymore. Same for decryptions.

Don't get me wrong. I think notedeck is fast. My only concern is "at what cost" (increased disk usage, increased memory usage). Exactly by how much is very unclear right now.

Keep pushing.

> Though I lazy load/compute the additional data structure (like the text parsing) only when the event is being placed in the same page that will be rendered

damus ios works the same way, but it is really annoying, leading to needing to recalculate the view after the parsing was done, which was janky. Now i don’t have to worry about it. If it’s in the db then it has everything it needs to render.

It definitely uses more disk space, but i just need to optimize the db on startup by removing old notes not in web of trust. I think nostur does something like this as well.

“Increased memory usage” is kind of misleading. It uses a lot of memory in the sense the page cache uses a lot of memory, but it does that anyway when reading from disk from anywhere. you can’t compare heap memory to a pagecache-backed virtual memory. They are not really the same thing. it’s more accurate to say it uses a small amount of fixed memory for the subscription queues and thats about it.

There is middle ground too, where nostrdb is used to cache certain kinds (vs everything) and the local relay is used for certain other kinds (vs always)

The main issue with the local relay is that you can't count on it so you need a database anyway