Earlier quoted context omitted.
A pool can invoke destructors when it is cleared. Might take a bit of overhead (if the pool is to support arbitrary classes), but you could retain the fast pointer-bump allocation.
Not Rust, C++, but in case anybody wants an example: https://github.com/eclipse/omr/commit/fd99ca42fdbed76cc00e68... TR::Region is the slab allocator used by the JIT in OpenJ9/OMR. The linked commit adds functionality for calling destructors of arbitrary types allocated in the Region.
Rust: Dropping heavy things in another thread can make your code 10000x faster
271–280 of 285 posts
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#272Earlier quoted context omitted.
Yes it’ll reduce latency, but doesn’t it also increase parallelism? A single-threaded program ought to improve overall, unless the extra overhead you mentioned dominates. A parallel program might improve or not. I think if you wanted to do deferred destruction right, ideally you’d mod an allocator to have functions like (alloc_local, alloc_global, free_now, free_deferred) to avoid exhausting memory. Traits could make…
> Also I admit I don’t understand why “you won’t have any backpressure on your allocations,” shouldn’t deferred destruction give you more backpressure if anything? I am probably confused. I think the point is that, if the same thread is doing both allocation and de-allocation, the thread is naturally prevented from allocating too much by the work it must do to de-allocate. If you move the de-allocation to another thr…
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#273Earlier quoted context omitted.
My understanding is that finalizers are special cased for a generational GC, have a tendency to introduce significant overhead, and (as with any GC scheme) generally run at unpredictable times. My impression is that RAII idioms are strongly discouraged in conjunction with most GC ecosystems.
Actually, RAII idioms are generally encouraged, but finalizers are not. For the rare few classes that hold resources in GC languages, the Resource is usually Acquired at Initialization as well, and released in a special method (IDisposable.Dispose() in C#, AutoCloseable.Close() in Java). There is also usually some special syntax for automatically calling this syntax when the object exits some scope, though that scope…
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#274It'd be interesting to implement this on a type that would defer all of these drop threads (or one big drop threads built off a bunch of futures) until the end of some major action, like sending the http response on an actix-web thread. Could be a great way to get the fastest possible response time, since then the client has their response before any delay on cleanup.
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#275Some 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…
For example, I had the "million strings" problem once, literally millions. The solution was to put every string into a single large buffer and the pointers in another buffer. Not only I could deallocate everything at once but I also saved a bit of RAM by not aligning (not needed for strings).
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#276It'd be interesting to implement this on a type that would defer all of these drop threads (or one big drop threads built off a bunch of futures) until the end of some major action, like sending the http response on an actix-web thread. Could be a great way to get the fastest possible response time, since then the client has their response before any delay on cleanup.
There is no such thing as a free lunch here, so it would reduce the unloaded response time but should have no effect (or a negative impact) on a highly loaded server's response time. I'm finding this out when benchmarking a message passing/queue management system. Anything I do to defer work onto a separate threadpool improves latency up to a point, then reduces throughput.
This situation you describe sounds a lot like dealing with garbage-collection cycles, so you give a good recommendation on something to watch out for, as rust performing at the level of a GC'd language removes a big reason for choosing rust.
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#277Earlier quoted context omitted.
But the spec usually has some implicit assumptions. Usually it's "app doesn't leak memory" in the same way nobody explicitly specifies "result of an addition of natural numbers should match ...". We don't go around saying "oh, you didn't want modulo 5 arithmetic? You should've put that in the spec, not rely on some contrived absolute truth".
Okay, but we're talking about an application, a piece of software who's primary intention is to run for a short period of time, parse a text file and transform it. It will be ran many many many times a day by developers whose time is expensive. Language servers are a very new concept in terms of being part of the day-to-day tool chains for most developers. Trading garbage collection for compile time was absolutely a…
C++ had its very first language servers via Lucid's Energize C++ and Visual Age for C++ v4.
Here is the 1993 video and related paper from Lucid.
https://www.youtube.com/watch?v=pQQTScuApWk
http://www.dreamsongs.com/Cadillac.html
And some information regarding VA, unfortunately most is missing from online world.
https://www.ecomstation.it/pido2/home/esterni/vac40os2.pdf (codestore)
http://www.edm2.com/index.php/VisualAge_C%2B%2B_4.0_Review
It is also why Delphi, VB and C++ Builder were already such a pleasure to use versus the Makefile and vi world of UNIX.
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#278Earlier quoted context omitted.
EDIT: See kevincox's reply. Rust will bitwise copy the containing type , which is typically very cheap. For example, it you move a String, it will copy the String struct, which contains a couple pointers and a length (or something along those lines). Importantly, it will not copy the underlying char array. I was thinking of the following code, where I believe the assignment to y is actually free. Though apparently th…
That's not exactly true. In C++ terms, the example code is moving a value: std::map foo; someFunction(std::move(foo)); And not moving a pointer like: std::unique_ptr > foo = ...; someFunction(std::move(foo)); So it copies sizeof(std::map ), not a pointer.
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#279Earlier quoted context omitted.
> after all the main point of, for example, destructors in C++ is to make sure you don't leak memory, which the GC solves No, C++ destructors are used for finalizers, not memory management. Memory deallocation is a particular use case for finalizers which is avoided when performance is a concern. > Another point is the C++/Rust pattern of each object recursively freeing the objects it owns presumably leads to slower…
> No, C++ destructors are used for finalizers, not memory management. In the original comment I may have overstated this. I was ignoring the other uses of destructors because the context of the discussion was memory management. But memory management is a huge portion of what destructors do in C++. Consider a vector of strings (`vector `). The destructor deallocates the memory for all the strings, then deallocates the…
A vector (or binary tree as you mentioned later) of heap allocated elements in a performance critical path is a likely candidate to be redesigned if possible.
> As far as I can tell, you either have to pointer chase or use a custom allocation strategy. At some point with the second option, you're basically creating an ad-hoc garbage collector.
A custom, ad-hoc strategy is the way to go if you need them dynamically allocated and performance at the same time, yeah.
I wouldn't call that a GC, though. A GC usually refers to a global solution.
> But I think we may be in vigorous agreement here
Sounds like it!
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#280Rust tries to be zero cost while providing abstractions that make it seemingly a high level language but ultimately things like this show that it's not exactly zero cost because abstractions can incur hidden penalties. There needs to be some internal syntax that allows a rust user to explicitly control deallocation when needed.
If I started reading code where people would randomly move a value into another thread and essentially do nothing I would be extremely confused. Any language that begins to rely on "trick" or "hacks" as standard patterns exposes a design flaw.
Maybe if rust provided special syntax that a function can be decorated with so that it does deallocation in another thread automatically? Or maybe an internal function called drop_async...? This would make this pattern an explicit part of the language rather than a strange hack/trick.