Skip to main content


Fun project: a #memory manager for multi-lang applications (#c, #cplusplus #assembly #fortran) in which workflow management is done by #Perl. Currently allocates using either #perl strings or #glibc malloc/calloc. Other allocators #jemalloc coming soon.
https://github.com/chrisarg/task-memmanager
in reply to Christos Argyropoulos MD, PhD

cross-runtime memory management was a major PITA back in the day. CORBA was available only as a C binding during web 1.0; and trying to use it with C++ objects was OMG disaster. (That the API that I needed wasn't fully implemented made things worse, but the memory management made that hard to determine!)
in reply to Bill Ricker

@BRicker I am having uncomfortable flashbacks to my actual day job right now, where we mostly look at multi-language memory management and go "eh, there's plenty of memory, nevermind" and then build a binary with C++, Go, and Java in it and just serialize/deserialize all the objects as they cross boundaries.
in reply to Bill Ricker

@BRicker ah, then you just throw even more memory and cpu at it. At least until someone with zero fucks to give and who is extremely grumpy starts storming around and yelling at people. (Not that I’ve done that twice or anything)
in reply to Dan Sugalski

@wordshaper
if I understood @ChristosArgyrop 's post, his CPAN module will provide memory that Perl can pass to C++, C, Fortran, and might work with Go or Java?

(Gives us a factual justification to write the main program in Perl ? 😁 )

in reply to Bill Ricker

@BRicker @wordshaper The dataflow logic requires a high level lang that can support different perspectives (remember some of us are just academics who want to develop rapid prototypes fast) and not get tied down to OOP or procedural languages. The type of the data is text (lots of it) and some of the manipulations are best with the packed instruction sets in assembly (that's why I have a PerlAssembly github repo, I am playing with the combination).
in reply to Christos Argyropoulos MD, PhD

@BRicker @wordshaper Which brings us to the next point. The allocators are a bizarre and arcane area of computer science. The last time I cared was in 1989 as a teenager when I was FAFOing with my atari st. Recently I had to visit some text based operations for biological sequence analysis and not only discovered that it is not 1989 anymore, but different workloads need different libraries for performance. I did benchmark Perl's mem allocator and oh boy it is fast (relative to glibc mallloc)
in reply to Christos Argyropoulos MD, PhD

@BRicker Allocator design is one of those things that are both bizarre and uninteresting to most people. Changes that look good in microbenchmarks behave really badly in actual use, and changes that have no reason at all to affect performance can make things go much faster. Or slower. (Usually slower)

We mess with allocators occasionally at work, and the standard glibc one is... not too hard to beat for performance.

in reply to Dan Sugalski

@wordshaper
In the late 1980s we considered adding a mark-sweep GC to our OS/2 PM port of Objective-C.
In retrospect, reference counting might have been a better choice?
(Alas our downstream client projects were all canceled or deferred, so while the port per se was successful, the GUI tool was never finished, so iirc GC optimization never happened?)
in reply to Bill Ricker

@BRicker Refcounting tends to be more systemically expensive (though not always) and definitely easier to mess up, but on the other hand it has more predictable performance characteristics and generally more predictable destructor characteristics.

In the '80s I'd say that refcounting was a better option, though, all things considered. That probably shifted in the early '00s, though there was a period where both were OK.

in reply to Dan Sugalski

@wordshaper @BRicker One of the experiments I will like to do with https://metacpan.org/dist/Task-MemManager
is a comparison of these strategies. I use perl's ref counting for immediate destruction, but the inside out object allows one to reclaim memory periodically. Again Dan's point about mem management performance being highly sensitive to task is very relevant to the choice of strategies to reclaim memory.
in reply to Christos Argyropoulos MD, PhD

@wordshaper @BRicker I do believe all of this is exactly why languages like Zig have gained some credence. Low level enough to do most things, but smart enough to let you design the allocators as-needed for each set of tasks.
in reply to necrophcodr

@necrophcodr @wordshaper
That's why i like Test-Driven Development.
Instead of the parser/compiler telling me I'm an idiot 40 times an hour, in TDD the test suite tells me I'm a genius 5-10 times an hour.
in reply to Bill Ricker

@BRicker @necrophcodr Are you sure? I feel like the test suite tells me "you're missing something subtle, heh heh heh..." several times a day.
in reply to Dan Sugalski

@wordshaper @BRicker @necrophcodr This reminds of the days before *widespread* use of cat scans for abdominal pain. Surgery textbooks as recently as the late 90s were saying that if a surgeon didn't needlessly operate on 1/5 cases of appendicitis, they were certain to have missed (and hurt) an unknown number of inflamed appendices. So without the compiler telling one they are an idiot, how can you be sure your test successes covered all the cases?
in reply to Christos Argyropoulos MD, PhD

@wordshaper @BRicker unless you write perfect tests, how can you be sure all the test cases even exists? Surely it's a matter of gradually improving the systems, and tests are but one manner of doing so.
in reply to necrophcodr

@necrophcodr @wordshaper @BRicker Unless one can formally prove their code is correct (and provability is hard), one at best may use a formal experimental design approach and test via statistical methods IMHO. This approach is often used in software for numerical approximation & statistical computations to generate estimates of error. Perhaps something similar can be done for software that does not target these areas (along with the compiler shaming during the pre-test development?)
in reply to Christos Argyropoulos MD, PhD

@wordshaper @BRicker I won't argue for or against this, as it is above my skill level (despite working in a data science department).
I encourage you (and others) to experiment with such approaches and share the findings for us "the masses" to learn and grow from.
For now, I will continue to write my software decently, but without much testing. Fortunately, it is rarely an issue where I work, if errors are made.
in reply to necrophcodr

@necrophcodr @wordshaper @BRicker The compiler is my test 😂😂😂
(Just surprised that I had not seen much about testing components using statistical methods outside scientific computing)
in reply to Christos Argyropoulos MD, PhD

@necrophcodr @wordshaper

I was actually trained in formal proof of algorithm correctness, as part of my day job.
(the cold war was a weird time.)
Since then, I proved one loop invariant with termination for actual use PER DECADE for a while, and none lately.

in reply to necrophcodr

@necrophcodr @wordshaper
there are several styles of testing.
Interface testing should reason about expected data cases.
Code coverage testing requires at least one test to exercise every reachable line of code (and delete the unreachable ones!)
etc
in reply to Bill Ricker

@necrophcodr @wordshaper

Test-First or Test-Driven testing is different; it doesn't test "correctness", it tests for regression, the next change inadvertently undoing a prior feature.
The outline is when trying to fix a bug (or add a feature, first thing is to write a test (or a few) that FAILS initially, thus demonstrates the bug (or whose failure shows the requested feature didn't already exist), but should pass once fixed (added).
Only then add the fix (feature).

in reply to Bill Ricker

@necrophcodr @wordshaper
Once the bug is moderately well understood, reproducing it with a unit test should be simple.*
(And if the feature is well understood, likewise.)

* assuming the API is built with unit-testibility in mind;
the needed dependency-injection or unit mocking to allow testing just one subroutine/method in isolation may be quite complex in some baroquely complex API/frameworks!

in reply to Bill Ricker

@necrophcodr @wordshaper
NOTE: I do _not_ claim Unit Testing is _sufficient_.
Some unit-test evangelists attempt to claim so, but it's unwise, as it makes the assumption that the callers will call the routine correctly same as the tests do !
Some intergration tests are needed, perhaps end-to-end (requires rewinding database, and comparing masked dates etc, somewhat tricky but doable)
or ...
in reply to Bill Ricker

@necrophcodr @wordshaper
... or perhaps half-stack testing, mocking API client and backend DB but testing transactions with same API input cause same mocked backend reads and writes as well as same API results.

What is total test coverage? Well.
If you know what the application is supposed to do, you know half of the test cases that are important.
(and if not well ... it's not a product it's a toy)

in reply to Bill Ricker

@necrophcodr @wordshaper

The other half are listing what the application (or module etc) should NOT do.
These are hard for most naturally optimistic* programmers to conceive.
Seeing these edge cases is the value-added that Testing professionals provide.
*(If we couldn't always falsely believe the next compile would work, we'd find other employment!)

in reply to Bill Ricker

@necrophcodr @wordshaper
Some few of us can make constructive use of cognitive dissonance to both code&debug and also imagine edge-cases for testing; probably helps that I did information security and provable algorithms in my formative years, I see the FNORDs.

(Once one gets in the habit of seeing edge cases, it's f****g hard to UNsee them.
I've been trying to leave INFOSEC for 35 years; even retiring doesn't change that.)