6 ms·
I think the last sample needs a `fba.reset()` call in between requests. BTW, I used zig a lot recently and the opaque allocator system is great. You can create
by eknkc 2y ago
I think the last sample needs a `fba.reset()` call in between requests.
BTW, I used zig a lot recently and the opaque allocator system is great. You can create weird wrappers and stuff.
For example, the standard library json parser will parse json, deserialize a type that you requested (say, a struct). But it needs to allocate stuff. So it creates an arena for that specific operation and returns a wrapper that has a `deinit` method. Calling it deinits the arena so you essentially free everything in your graph of structs, arrays etc. And since it receives an upstream allocator for the arena, you could pass in any allocator. A fixed stack allocator if you wish to use stack space, another arena, maybe jemalloc wrapper. A test allocator that checks for memory leaks.. Whatever.
- latch 2y agofixed, thanks.
- hinkley 2y agoWhen I read json I always end up holding onto values from some of the keys. Sometimes the keys too if the node is abstract enough. I assume the receiver then has to know it has to clone all of those values, yes? That seems a little tricky for general code and moreso for unit tests.
- anonymoushn 2y agoYou can pass the json deserializer an allocator that is appropriate for the lifetime of the object you want to get out of it, so often no copying is required.
- saagarjha 2y agoRight, but that means you lose the simplicity and performance benefits of an arena allocator.
- anonymoushn 2y agoI've mainly written unusual code that allocates a bunch of FixedBufferAlocators up front and clears each of them according to their own lifecycles. I agree that more typical code would reach for a GPA or something here. If you're using simdjzon, the tape and strings will be allocated contiguously within a pair of buffers (and then if you actually want to copy from the tape to your own struct containing slices or pointers then you'll have to decide where that goes), but the std json stuff will just repeatedly call whatever allocator you give it.
- saagarjha 2y agoWell, see, the problem is that you’re going to have to keep the allocator alive for the entire lifetime you use any data whatsoever from the JSON. Or clone it manually. Both seem like they largely negate any benefit you get from using it?
- forrestthewoods 2y agoUnit tests are trivial because you can probably use a single arena that is only reset once at the end of the test. Unless the test is specifically to stress test memory in some form. > I assume the receiver then has to know it has to clone all of those values, yes? The receiver needs to understand the lifetime any which way. If you parse a large JSON blob and wish to retain arbitrary key/values you have to understand how long they're valid for. If you're using a garbage collection language you can not worry about it (you just have to worry about other things!). You can think about it less if the key/values are ref-counted. But for most C-like language implementations you probably have to retain either the entire parsed structure or clone the key/values you care about.
- ComputerGuru 2y agoI assume the following is perfectly doable from a technical perspective but is there any community support for using multiple allocators in this case to, eg parse general state to an arena and specific variables you want to use thereafter to a different allocator to remain long lived?
- CyberDildonics 2y agoWhy wouldn't this be better done with a class that takes care of its memory when it goes out of scope?
- anonymoushn 2y agoThere are no automatically-invoked destructors in Zig.
- saagarjha 2y agoPerhaps if this was added it would prove to be a better solution in this case?
- anonymoushn 2y agoIt would prevent you from writing the bug at the top of the thread. I have stopped considering this sort of thing as a potential addition to the language because the BDFL doesn't like it. So realistically we must remember to write reset, or defer deinit, etc. This sort of case hurts a little, but people who are used to RAII will experience more pain in cases where they want to return the value or store it somewhere and some other code gains responsibility for deinitializing it eventually.
- i4k 2y agoOn the other hand, is more clear where things are released. When over relying on destructors, often it becomes trick to known when it happens and in which order. This kind of trade off is important to take into consideration depending on the project.
- juliangmp 2y agoMaybe I'm too used to C++ and Rust but I don't find it tricky at all. Its very clearly defined when a destructor (or fn drop) is called as well as the order (inverse allocation order). What I would like to see would be some way of forcing users to manually call the dtor/drop. So when I use a type like that I have to manually decide when it gets destroyed, and have actual compile checks that I do destroy the object in every code path.