Show HN: Molecule – Streaming, zero-allocation protobuf decoding in Go
github.com
github.com
Given that JavaScript runs on restrictive clients, it must have libraries in spades for this kind of a thing, but I couldn't find many. I'm really interested in techniques that are generally employed in languages like Java, Golang, Rust, C/++ that are worth translating over to JavaScript, especially now that TypedArrays are a reality. I'm pretty sure there's more to zero-alloc than just Buffers, Object pools, and Recyclables, but I can't seem to find good resources to get started with this.
[0] https://github.com/rs/zerolog
[1] https://github.com/ronomon/hash-table/blob/master/README.md
Don't know about Rust, but Go has slices built into the language, and C++ has it in the standard library. Learning idiomatic slice-handling makes working with data sans allocation much, much easier.
Rust also is very big into slices as well.
If your use case is really simple, and you want the fastest possible proto decoding, you can hand-roll it pretty easy.
message point { fixed32 x = 1; fixed32 y = 2; }
Then your code is structured such as var x uint32
var y uint32
for len(buf) > 0 {
switch buf[0] {
case (1<<3) & 5: // Field 1, type fixed32
x=binary.LittleEndian.Uint32(buf[1:])
buf = buf[5:]
case (2<<3) & 5: // Field 2, type fixed32
y=binary.LittleEndian.Uint32(buf[1:])
buf = buf[5:]
default:
// Freak out somehow
}
Improve the exception hardness of this code to the extent that it suits your use case.Do you think I could just manually inline the decoding code as much as possible in the molecule library, or does it need a different API?
Also if you open a P.R I'll merge it :)
for len(buf) > 4 {Just because you're using a GC'd language doesn't mean that you should give no thought whatsoever to the garbage your program is generating.
Maybe the allocations are more obvious, because you usually have to write them out yourself (heap-allocating RAII containers excepted), but the problem is the same.
Garbage collected memory allocations would be the subset of allocations for which the compiler was unable, through escape analysis or otherwise, prove that an allocation's lifetime extends past (for example) its lexical scope, in which case the analog of C auto allocation would suffice.
a) rewriting in C++
b) pooling some objects
Which one is the right call?