Box to save memory in Rust
41–50 of 59 posts
Re: Box to save memory in Rust
#42Earlier quoted context omitted.
"You have 400 megabytes of zeros in " is probably a pretty easy heuristic to add.
That may be surprisingly difficult in Rust. We generally think of Option using O to represent None. However, it can actually use any invalid value of T
And in this particular context None of Option is the bit pattern for a carefully chosen impossible 24 byte slice, all zeroes is of course a completely valid way to spell 24 of the ASCII NUL U+0000 character so we can't use that to signify None, but many 24 byte slices are not valid UTF-8 encodings.
When some day I get to make my own BalancedI8 in stable Rust (the 8-bit signed integer except without the slightly annoying and rarely needed most negative value -128) then None of Option will occupy the bit pattern for -128 which is 0x80
Re: Box to save memory in Rust
#43Very often if you have text, which this does, you can make huge savings by being intelligent with the text. Rust intentionally provides the simplest possible growable string buffer String, which is literally (under the hood, you can't poke this legitimately) Vec plus the promise that this is UTF-8 text. But you might find your needs better served by one (or several) of: Box -- you don't need capacity, so, don't store…
I wish Box and Option got specialized specialized shorthand syntax in Rust say `^`/ `? or something like that. Option -> SmithyTrait^?
I think I agree though, especially with Option. Swift’s option syntax (and kotlin’s which is similar) is so much better, a simple question mark in the type. Options are important enough that dedicated syntax makes so much sense. Rust blew their chance here with ? meaning “maybe early return”, it would have been a lot more useful as an Option indicator.
Re: Box to save memory in Rust
#44Earlier quoted context omitted.
I wish Box and Option got specialized specialized shorthand syntax in Rust say `^`/ `? or something like that. Option -> SmithyTrait^?
Box used to be ~T early on in rust… (then it became a `box` keyword, before being removed entirely.) They got rid of it because they wanted to move more things into libraries and have a less opinionated compiler. I think I agree though, especially with Option. Swift’s option syntax (and kotlin’s which is similar) is so much better, a simple question mark in the type. Options are important enough that dedicated syntax…
Re: Box to save memory in Rust
#45Earlier quoted context omitted.
I wish Box and Option got specialized specialized shorthand syntax in Rust say `^`/ `? or something like that. Option -> SmithyTrait^?
Box used to be ~T early on in rust… (then it became a `box` keyword, before being removed entirely.) They got rid of it because they wanted to move more things into libraries and have a less opinionated compiler. I think I agree though, especially with Option. Swift’s option syntax (and kotlin’s which is similar) is so much better, a simple question mark in the type. Options are important enough that dedicated syntax…
Note that both Option and Result implement that same trait.
Perhaps if try blocks ever become a thing... we can finally use it for our own types ;)
Re: Box to save memory in Rust
#46Earlier quoted context omitted.
That may be surprisingly difficult in Rust. We generally think of Option using O to represent None. However, it can actually use any invalid value of T
For example None of Option is the bit pattern for the integer -1, the invalid Unix file descriptor And in this particular context None of Option is the bit pattern for a carefully chosen impossible 24 byte slice, all zeroes is of course a completely valid way to spell 24 of the ASCII NUL U+0000 character so we can't use that to signify None, but many 24 byte slices are not valid UTF-8 encodings. When some day I get t…
Do you know a solution to this?
Re: Box to save memory in Rust
#47Earlier quoted context omitted.
There's really an endless list of these optimizations. A few I've used (though not necessarily in rust): Atoms: Each string can be referenced with a single u32 or even u16, and they're inherently deduplicated. Bump allocator: your strings are &str, allocation is super fast with limited fragmentation. Single pointer strings (this has a name, I can't think of it right now): you store the length inside the allocation in…
> There's really an endless list of these optimizations. These aren't really optimizations. They are specialized implementations that introduce design and architectural tradeoffs. For example, Rust's Atom represents a string that has been interned, and it's actually an implementation of a design pattern popular in the likes of Erlang/Elixir. This is essentially a specialized implementations of the old Flyweight desig…
In my opinion, there's no magic in the software engineering. Everything (or almost everything) is a system that can be described, explained, modified and so on. Applications, libraries, operating systems, kernels, CPUs/RAM/GPU/NPU/xPU/whatever silicon there is, ALUs/etc, transistors, electricity, physics... That's nowhere near "magic". There's always some trade-offs, it's just that you may not be aware of them initially.
Re: Box to save memory in Rust
#48Earlier quoted context omitted.
For example None of Option is the bit pattern for the integer -1, the invalid Unix file descriptor And in this particular context None of Option is the bit pattern for a carefully chosen impossible 24 byte slice, all zeroes is of course a completely valid way to spell 24 of the ASCII NUL U+0000 character so we can't use that to signify None, but many 24 byte slices are not valid UTF-8 encodings. When some day I get t…
I often wish this type existed, but didn't find a way to define the niche value for the compiler to optimize the None-case. Do you know a solution to this?
So, the long answer with lots of reading material is that you want "Pattern Types" and who knows when that could land in Rust. Pattern types are a simple Refinement Type, you can go absolutely wild with refinement in theory and some niche languages go much deeper but all we want here is to say "Only these values of the type are allowed" and by implication all bit patterns not used for those values are a niche and Rust would optimise accordingly.
Rust doesn't (even unstably) have Pattern Types so you might wonder how NonZeroU32 works for example, or indeed OwnedFd, and similar types. For these types there's a permanently unstable "compiler only" feature flag which allows you to explicitly specify the niche, that's how they're made. So, if you're comfortable writing unstable nightly-only software you can do this today, go look at the guts of NonZeroU32 for example.
If you want to write Rust software for ordinary people who use stable Rust you have two options today and for the indefinite future in which Pattern Types are not stable:
1. Enumerations: An enumeration which has say 5 values clearly doesn't need byte values 0x5 through 0xFF, so Rust stably promises this is a niche. For BalancedI8 that's kinda messy with 255 values but tolerable, some real crates use this trick or one related to it and they work fine - for a hypothetical BalancedI16 it's imaginable to create 65535 values but silly, and for BalancedI32 clearly we should not expect the compiler to accept an enumeration with 4 billion+ named values so no...
2. XOR trick: Rust provides NonZeroI8 for example. We can "make" BalancedI8 by providing accessors which always XOR -128 (0x80) with the value and then actually internally we store the NonZeroI8 instead, at runtime now operations incur an extra XOR which is a very cheap ALU operation. This works for any "Not this" value because of the properties of the XOR operation, so unlike with enums this is practical for BalancedI64 for example.
Re: Box to save memory in Rust
#49Earlier quoted context omitted.
For example None of Option is the bit pattern for the integer -1, the invalid Unix file descriptor And in this particular context None of Option is the bit pattern for a carefully chosen impossible 24 byte slice, all zeroes is of course a completely valid way to spell 24 of the ASCII NUL U+0000 character so we can't use that to signify None, but many 24 byte slices are not valid UTF-8 encodings. When some day I get t…
I often wish this type existed, but didn't find a way to define the niche value for the compiler to optimize the None-case. Do you know a solution to this?
Eventually rust will likely gain pattern types as a more generally useful version of the features used in nook. There is even some actively ongoing work on this [3]
1: https://github.com/tialaramex/nook/blob/main/src/balanced.rs
Re: Box to save memory in Rust
#50Very often if you have text, which this does, you can make huge savings by being intelligent with the text. Rust intentionally provides the simplest possible growable string buffer String, which is literally (under the hood, you can't poke this legitimately) Vec plus the promise that this is UTF-8 text. But you might find your needs better served by one (or several) of: Box -- you don't need capacity, so, don't store…