boricj
Object pools, with indices and generations. Way, way easier than meddling with pointers, cheaper than shared_ptr/weak_ptr and no clean-up required when deleting stuff because the stored generation won't match the new object's generation. You can even make that default-constructible if you increment the generation on instantiation too (so that only even generations are alive) and hide it all behind high-level abstractions with C++.
Though my knowledge of these techniques come from 2000s video game architectures, as games like GTA: Vice City are known to use it.
"Unclean" code for this is putting objects in a table, giving objects a generation (that increments whenever you create/delete one) and storing pairs of (index, generation) numbers everywhere you need a link. Link is live only if the generations matches and since only odd generations are live objects, default construction means no link. Lifted straight from 2000s video game tricks and with modern C++ it's basically all encapsulated away.
I've made that refactoring in a codebase, not because of speed but because of maintenance and memory fragmentation concerns. Sometimes, the clean solution really isn't the right one and it's really sad that compsci only ever teaches classical data structures, like we're still coding in the 1970s on computers with no caches that don't suffer from pointer chasing.
That's the least forgiving kind of chip when it comes to performance: fast enough to outpace main memory by two orders of magnitude, yet the slightest speed bump (branch misprediction, cache miss) stalls it without any ability to reorder around it.
On the other hand, in my team I wrote my custom C++ STL containers that allocate inline, SAX-style processing libraries and an object pool with links that use index+generations like 2000s video games... on a STM32H5 with less than a megabyte of RAM.
Mechanical sympathy feels like a lost art to people I demonstrate it to... and I had to demonstrate to the first team with benchmark numbers that I would not be the bottleneck between us by orders of magnitudes.
I would prefer ms-edit or nano if I have to edit text files from the terminal.
Word-of-mouth happens when someone who has a need finds your project, uses it and likes it so much they talk about it to other potential users. It's effectively a chain reaction and the way to leverage it is to make something people want to use.
In fact, I see this as an opportunity to build anew and better. When you're no longer constrained by legacy baggage and constraints, you can collapse layers and introduce new ones that better fit what you're creating.
I'm doing that in the project I'm working on at work. Being able to redefine how serialization/deserialization fundamentally works and interacts with domain objects is giving us unbelievable expressiveness, not by the amount of code written (in fact, it's heavily factorized across layers that were historically separate), but by exploring new designs paradigms.
Don't just read these books. Write some new ones.
Not a lawyer, but wouldn't an illegal immigrant owe no allegiance to breach and therefore couldn't commit treason?
Say, like a multi-scale hierarchical half popcount vector (first/second half, first quarter+third quarter/second quarter+fourth quarter all the way to odd/even bits), where fumbling one private key for another or xkcd-ing 4 as a private key would be detected, but still reveal no information on a truly random series of bits and be understandable by non-technical people in the room.
You could ask the same about the Opinel No. 8 knife. Same thing since 1890s, one minor update every 50 years or so. It's still sold by the bucketload today for about €10.
It's just French, the same way a Lada is just Russian, a Mini Cooper is British or a Fiat 500 is Italian. It's part of post-WW2 cars that were cheap to buy, cheap to operate, cheap to fix and with production numbers in the millions.
I'm working on an embedded system with a MCU and I've benchmarked JSON serialization at over 500 KiB/s (through a HTTP GET request) using my own library. Deserialization is slower, but that's partly because I have super-linear algorithms downstream of the parsing.
CBOR is much nicer and faster to work with (smaller documents, definite length strings directly consumable) and I do support it in my library, but I derive most of my performance gains by ditching DOM-style APIs and using stream processing instead. Allocating nodes and chasing pointers all over the heap sucks for performance, especially for large documents, regardless of the format (and that's assuming it even fits within available RAM).
Humans too do that for matching decompilation. Or at least I imagine so, given that I personally refuse to do that.
People have different goals and will use different techniques to achieve them. The video game reverse-engineering/decompilation community isn't a hive-mind, I went ahead and created ghidra-delinker-extension because I had my own ideas on how to do that.
The quirks of that console for this is that the CPU takes a 6 cycle stall on any read from main RAM (it's not even stall-on-use) and doesn't have a data cache. That would make it a very poor fit for this, so I had to improvise a bunch of tricks to reclaim performance:
- Made all of my hot loop fit within one function, so that it fits entirely in the 4 KiB direct-mapped instruction cache (so less than 1024 instructions)
- Wrote a C++ template that can trampoline a function call into the 2 KiB scratchpad
- Used the rest of the scratchpad for a CLUT table because it doesn't stall on read
- Used the GTE to transform the N set of coordinates while the CPU stalls fetching the N+1 set of heightmap data
- Figured ways to abuse the GTE into transforming more points per instructions than it theoretically can, taking advantage of simplified formulas compared to real 3D projection
- Write the rectangle primitives straight to the GPU registers instead of going through a display list
It's such an abuse of the PlayStation that PCSX-Redux and DuckStation disagree on its performance by up to a factor of two. I should finish it someday and see how it runs on real hardware...
At home, ghidra-delinker-extension [1], a Ghidra extension for exporting relocatable object files (or in other words, stripping programs for parts like Doctor Frankenstein). Absurdly complex, got me a poster session at SURE workshop at ACM CCS last year, as a hobbyist.
It's the vindication of Gaullism half a century after De Gaulle's death, the concept of strategic autonomy is getting traction in the rest of Europe. It's not that we can't be friends, but that we shouldn't let our future be gambled in the hands of Wisconsin voters every two years.
You don't know the pain of others, especially what others hide from you.
I recently implemented a custom C++ container for a path whose components could be iterated, backed by a std::string. I just store indices and a reference to the string, such that my iterators are not invalidated if the std::string gets reallocated after being modified. Far less error prone for little added cost.
The first two formats I've implemented as fully streaming, the serializers emit into an output iterator one character/byte at a time and the deserializers only need to hold one value at a time (mostly for strings, and not even for CBOR's byte arrays, which are streamed). BSON requires full document instantiation because of byte offsets and is genuinely anti-streaming in its design.
I happen to have implemented a serializer for YAML, fully streaming, mostly as a compact-ish human-readable debug data representation. I can scarcely think of fates worse than having to write a spec-compliant YAML parser.
I've already seen the horrors that lurk inside of poorly-written 90s video games. Hard pass.
Somehow, it landed me an academic poster presentation [2] at the 2025 SURE Workshop, part of ACM CCS 2025 held in Taiwan. As a hobbyist playing Doctor Frankenstein with bits instead of gibs in my spare time, that is "received an invitation from Hogwarts"-levels of impossible, given that ACM CCS is the biggest academic cybersecurity conference in the world.
It also somehow grew a small community online around it, mostly within the Windows decompilation scene. It's not finished (as it is the kind of project that is practically endless), but I don't see how I could top that.
[1] https://github.com/boricj/ghidra-delinker-extension
[2] https://boricj.net/2025/10/25/ghidra-delinker-extension-and-...
I used to. Back at university and at the pub. Graduated almost a decade ago and had the one drink too many a while back. The soul's too broken to draw for now. The skill's there, but the heart isn't.
Maybe I'll be able to draw again someday.
Modern toolchains, programming languages, dev cartridges and libraries from the community makes all the difference. Outside of some niceties like ICE (gotta write that GDB stub for target hardware at some point), it's not that different from what you'd experience with modern embedded work.
I'm working on a voxel space renderer homebrew for the PlayStation. I only have so many cycles to spend on rendering before it becomes a slideshow, so I count them in my hot rendering loop and parallelize work as much stuff as I can, even across memory load stalls from main RAM.
I've worked on a basic network accessory card with a STM32 MCU that is extremely overkill for what it needs to do. We haven't bothered making any performance or memory optimizations whatsoever, writing plain C++ almost as if we were on server-class hardware because we had such egregious margins.
The first question to ask is not whether something can leverage SIMD, it's whether the performance requirements are met or not (although it's far too easy to not care when it's not your hardware that's struggling...).
Turns out there are tons of stuff that sip power (set-up boxes, Ethernet switches, NAS...) that can either be powered directly by Power-over-Ethernet or through a splitter (DC-DC converter). That can be handled by a PoE Ethernet switch, which itself is usually powered at 54VDC, so it's also an excuse to run a homelab on 48VDC and get rid of tons of power supplies.
However, DC isn't well suited for the entire home for several reasons, mostly due to cheapness and historical reasons. For example, AC breakers are dirt cheap because arcs naturally extinguish when current crosses zero volts, whereas DC doesn't.
There are areas where DC is used. I work on telecommunication gear where nearly everything is -48VDC, but the beefy copper busbars needed to push large amounts of power through them would make a homeowner cry at the expense. Higher voltage is possible to compensate, but you enter not-safe-for-touch territory and I'm not knowledgeable about that.