Live data from Hacker News

Rust: Dropping heavy things in another thread can make your code 10000x faster

abramov.io

211–220 of 285 posts

Re: Rust: Dropping heavy things in another thread can make your code 10000x faster

#211
post #182

There is nothing unique to Rust about this; it is a very old technique. It is usually much inferior to the "arena allocator" method, where all the discarded allocations are coalesced and released in a single, cheap operation that could as well be done without another thread. That method is practical in many languages, Rust possibly included. C++ supports it in the Standard Library, for all the standard containers. If…

> C++ supports it in the Standard Library, for all the standard containers.

I don't know what the situation is today, but in the past, the GCC standard library containers had non-trivial destructors when running in debug mode. Ensuring their proper invocation was required to avoid dangling pointers in their book keeping. Non-obvious and painful to debug.

Re: Rust: Dropping heavy things in another thread can make your code 10000x faster

#212
post #158

Earlier quoted context omitted.

No worries. And to clarify, in context the point is that traversal fundamentally can't be avoided in the case of RAII. This defeats (what I see as) the primary use case of an arena allocator - deallocating an arbitrarily large chunk of contiguous memory in O(1) time regardless of object count. Of course this is all somewhat tangential to the original topic of generational GCs, where the RAII idiom also has significan…

I'm not sure its fair to say it defeats that use case. It only defeats that use case if you need RAII. Furthermore, in my experience, an arena is most useful when you allocate lots of small objects which is the least likely to case to need RAII.

I think we're violently agreeing?

RAII is the only use case I was speaking of there. Way back up thread the original post I responded to was talking about arena allocators in comparison to a generational GC and finalizers. The point is that a generational GC doesn't handle finalizers well, but neither does an arena allocator!

Re: Rust: Dropping heavy things in another thread can make your code 10000x faster

#213

Some important things I think people should note before blindly commenting: * The example code is obviously contrived. The real gist is that massive deallocations in the UI thread cause lag, which the example code proves. That very thing can easily happen in the real world. * I didn't see any difference on my machine between a debug build and a release build. * The example is preforming 1 _million_ deallocations. Tha…

>As an aside, compilers have used the trick of not free-ing data structures before, because it provides a significant performance boost. Instead of calling free on all those billions of tiny data structures a compiler would generate during its lifetime, they just let them leak. Since a compiler is short lived its not a problem, they get a free lunch (pun unintended), and the OS takes care of cleaning up after all is…

The bumper sticker is “Ada programmers prove the algorithm terminates.”

Re: Rust: Dropping heavy things in another thread can make your code 10000x faster

#214

Earlier quoted context omitted.

How are finalizers invoked if the structure isn't traversed? Would it just be optimized away none of the objects have finalizers? Hence my suggestion about the area allocators being a better point of comparison.

Maintain a collection of objects with finalizers associated with the generation; when an object is moved out of the generation, move the finalizer record with it. Then, just before the generation is discarded, run the finalizers. If the finalizers do something stupid like resurrect the object, have the runtime system notify someone with the authority to go beat the programmer with a stick.

Interestingly for the Rust GC I'm working both Drop and finalizers will be supported.

Do you happen to offer beat the programmer with a stick as a service?

Re: Rust: Dropping heavy things in another thread can make your code 10000x faster

#215

Some important things I think people should note before blindly commenting: * The example code is obviously contrived. The real gist is that massive deallocations in the UI thread cause lag, which the example code proves. That very thing can easily happen in the real world. * I didn't see any difference on my machine between a debug build and a release build. * The example is preforming 1 _million_ deallocations. Tha…

> As an aside, compilers have used the trick of not free-ing data structures before

In Clang, this flag is `-Xclang -disable-free`. Not from a Jedi...

Re: Rust: Dropping heavy things in another thread can make your code 10000x faster

#216
post #212

Earlier quoted context omitted.

I'm not sure its fair to say it defeats that use case. It only defeats that use case if you need RAII. Furthermore, in my experience, an arena is most useful when you allocate lots of small objects which is the least likely to case to need RAII.

I think we're violently agreeing? RAII is the only use case I was speaking of there. Way back up thread the original post I responded to was talking about arena allocators in comparison to a generational GC and finalizers. The point is that a generational GC doesn't handle finalizers well, but neither does an arena allocator!

Yes. We are violently agreeing

Re: Rust: Dropping heavy things in another thread can make your code 10000x faster

#217
post #117

Earlier quoted context omitted.

Yeah, I like Apple’s (Next’s) approach of pool allocation for each run through the event loop. Defer dealloc, drop pool at the end.

Apple's pools are for helping manage reference counts of returned objects (via autorelease) but aren't doing pool allocation (as any of those objects could escape, so you can't do the fast thing of just deallocating the pool). The normal memory allocator is used while in the scope of an autorelease pool.

right, so if you do

@autoreleasePool { [[[SomeObject alloc] init] autorelease]; }//someobject is release after exiting this scope

//inside main runloop, not inside @autorelease{} [[[AnotherObject alloc] init] autorelease];

//AnotherObject will be release at end of main runloop

[[NotAutoreleased alloc] init]; //will leak past runloop iteration

is that understanding correct?

Re: Rust: Dropping heavy things in another thread can make your code 10000x faster

#218

Earlier quoted context omitted.

Of the three compilers I've worked on in-depth, only one of them had a "normal" memory management scheme. One of them was unburdened by any thought of freeing stuff, and relied entirely on the application exiting for cleanup. This was very convenient to work with, and never ended up posing an issue. Another used a series of allocation arenas, where certain arenas would be cleared at certain points in the compiler pip…

Judging by the downvotes I am getting (with zero explanation as to why), I'd say that many misunderstood the "good practices" part and took offence, as if I said there's only one good practice. I was taught -- including at the start of my career when I used exclusively C/C++ (about 18.5y ago) -- to take care of all resources I was using and not rely on runtimes. I understand and appreciate different usages but to me…

I didn't downovte, but asides like, "sounds awful" and "nasty" definitely read as judgemental. Your other comments on this thread make you seem much more open minded than this one did.

Re: Rust: Dropping heavy things in another thread can make your code 10000x faster

#219
post #181

Earlier quoted context omitted.

Most compiler are not designed to run in daemon mode, specifically it's non-issue since their startup is normally fast. And the compiler and runtime are a different thing.

I realise that, but nowadays language servers are a pretty normal practice in no small amount of areas.

You mean like LSP? Why would a compiler and a language server be integrated in the first place? Clearly a LSP server wouldn't use a no-freeing strategy, but there's no reason why it would cause issue with a compiler. A compiler must terminate, assuming parsing isn't turing complete (like Perl) and that the source code is finite. This is why it's okay for it to leak memory.
Post reply on HN