← Back to context

Comment by i2talics

11 hours ago

> If you don't like arenas then that will push you towards avoiding allocations

I mean push in the sense of a pit-of-success, not making me do things because the alternative is unpalatable.

> managing frees one-to-one with allocations is a nightmare

It really isn't a nightmare if your language has tools to help you. I'm never particularly concerned about frees in Rust outside of thinking about room to optimize.

> Need something to live across connections? Use the general purpose allocator for those particular things.

Well, this is a determination you have to make very carefully and if you screw it up (like in the situation I was trying to outline) you have a subtle bug.

> Personally I mostly lean on fixed-size buffers, but if I'm writing Zig it's just little toy programs where blowing up when the buffer runs out of room is fine.

What's also fine is using malloc, which will have perfectly reasonable performance for your toy programs.

This is reinforcing my belief that Zig programmers actually just have a sort of aesthetic attachment to the idea of managing their allocations themselves and this has very little to do with the actual practical concerns of writing software that works. I'm a lot more sympathetic to the other reply that talked about library code improving flexibility for those relying on the library, than this comment that only thinks about the case where everything goes perfectly and using a fixed size buffer for no reason.

> I'm never particularly concerned about frees in Rust outside of thinking about room to optimize.

Zig's position, love it or hate it, is that you should be thinking about it. Dropping a Vec<String> in Rust is O(n). Have you ever clicked the X on an app and it takes 10 seconds to disappear? Stuff like this is part of the problem. You shouldn't have to traverse your process's whole memory space just to call exit(0).

If you have to write that for loop, the O(n) will jump out at you and push you towards an arena or FixedBufferAllocator or std.process.cleanExit, or any other solution to avoid the loop.

  • > Stuff like this is part of the problem.

    Measure, measure, measure.

    So often when people insist that a thing they don't like is "part of the problem" they haven't even thought about how much that "part" would be, although I suppose it's worse when they have thought and decided to go ahead anyway because the weasel wording might convince the hard of thinking.

    A guy who rounded up from $14.86 to $15 on some grant paperwork and got 14 cents he wasn't entitled to out of a government programme, and Ken Paxton inexplicably becoming very wealthy from a government job are both "part of the problem" but hopefully it's apparent which of these is worth fixing.

  • Just to let you know, `std::process::exit(...)` in Rust does not call any destructors. C++ also has `std::quick_exit(...)`. Applications exiting slowly is a problem caused by app developers.

    (There are cases where it also takes time because the OS does have to flush all open files during process teardown, etc., but this shouldn't generally be user-visible.)

  • Dropping vecs that contain strings does not make any Rust code in the real world slow. You would need to have a vec containing billions of strings, occupying several gigs of memory, before dropping such a structure took any perceptible amount of time. And for extreme cases like that, you can simply use arenas. The bumpalo crate is approximately as old as Zig is. The reason that people so rarely turn to arenas in Rust isn't because you can't do them, because you've always been able to, but rather because arenas are a very specific solution to a specific sort of memory access pattern, and going out of your way to strictly adhere to that pattern doesn't produce measurable differences for most software.

> This is reinforcing my belief that Zig programmers actually just have a sort of aesthetic attachment to the idea of managing their allocations themselves and this has very little to do with the actual practical concerns of writing software that works.

Indeed if you don't want to manage everything yourself I don't think there's a need to use Zig. The whole pitch is making everything explicit and not hiding control flow. And I do think that limits its usefulness to smaller-scale codebases.

Writing quality software doesn't require much from the programming language until your codebase gets very large and you're collaborating with a ton of people. If I'm expecting a codebase to grow to a large scale I'm not reaching for Zig for that. I don't trust _myself_ to keep that much Zig code tidy and correct let alone a big mob of developers and agents :)

  • My opinion is quite the opposite.

    With a small program, it's rarely difficult to work out what's going on. If your small program develops a performance problem, it's usually fairly tractable to work out what's going on, and modify it. In extremis, you can just rewrite the whole thing.

    Large programs are another matter. Hidden control flows in C++ (for example) can make pinning down performance problems extremely difficult. And then widespread refactoring can be extremely challenging.

    Zig forces everything to be an explicit interface, which should make maintenance work on large programs much more tractable.