3 ms·
The minor discussion on the C version's memory leaks reminded me of a neat trick. If you're developing a short lived application, like pkg-config, you can opt
by fpgaminer 9y ago
The minor discussion on the C version's memory leaks reminded me of a neat trick. If you're developing a short lived application, like pkg-config, you can opt to never deallocate. i.e. leak everything. In lightweight, short lived applications there's usually not a lot of incentive to deallocate; your application will never use much memory anyway and the deallocations waste time.
You can think of it like treating C as a garbage collected language, except the garbage collection cycle occurs only once at the end of the program :P
It really can be an effective trick. Deallocation isn't free, and under certain loads can be quite expensive.
The 1000+ leaks in the C version might actually be what's giving it the slight run-time advantage.
- andreasgonewild 9y agoOr take that even further and allocate a slab that's big enough to last the entire runtime and send malloc on vacation. It's worth repeating, with todays focus on web-frameworks, cloud-providers and dogmatics these ideas are slipping into obscurity; which is a shame given how beneficial they can be if your program fits the use case.
- sebcat 9y agoAnd, instead of using pointers into said memory, use indices so that the slab can be reallocated, or just mmap more pages following the slab if you own the process address space. Also, align properly. And having guard pages is always nice. Freeing on exit too, one single deallocation is pretty cheap. I've seen programs building ASTs with hundreds of millions of nodes, where all the nodes were allocated by a separate malloc call, and ref-counted... More than one-third of the startup time (which was counted in minutes) was calls to malloc and free. Some optimizations were made, but in the end we ended up reducing the size of the AST instead of fixing the allocations.
- pjc50 9y agoOuch. Last time I did any serious parser work I used a pool allocator so I could free all the nodes at once, so allocation was just a compare + increment operation. Although that was forced on me by the difficulties of error recovery in yacc.
- humanrebar 9y agoC++ actually supports this approach in the standard library and doing this is a really standard technique in some domains. That's what the allocator template parameter in vector and other containers is for.
- striking 9y agoIt's stop-the-world garbage collection, where collection only happens when the world ends. Side note wrt deallocations being somewhat slow: could something like Boehm conservative GC speed that up, by grouping all the deallocations together, or by doing them on a separate thread?
- agumonkey 9y agoOS delegated one pass GC.
- LukeShu 9y agoI remember one of those sysadmin stories, where a multi-terabyte `cp` command had seemingly completed all of its work, but was sticking around for days; slowly and pointlessly free()ing the 17GB hash table of hardlinks that it had built up; when it could have just exited and let the OS reclaim the memory. https://lists.gnu.org/archive/html/coreutils/2014-08/msg00012.html https://lists.gnu.org/archive/html/coreutils/2014-08/msg0001...