Several years ago, when my primary system was Slackware Linux on an x86 laptop, I wrote a full-screen console Usenet reader. I prototyped it in Python with Curses. I intended to re-write it in C/C++ later, but at some point, I realized it was good enough and I liked the flexibility. I did make a concession for decoding attachments. The Python libraries had support for MIME base64 and uuencoded data, but they did not handle yEnc. Decoding yEnc data in Python code was painfully slow. Since I needed an external tool for decoding yEnc, I made a general solution. The reader program has a command to save messages to individual files in the current directory. The decoder scans through its command line arguments, collates multi-part files if needed, and saves their data to the designated filename.
This worked pretty well, and when I moved from Linux to OS X, it ported with one trivial change. (Terminal.app will not make the cursor invisible, so I had to catch an exception in my screen-handling code.) Recently, though, I have been running into a resource problem. The original decoder saved decoded file parts in memory and reported missing parts at the very end. In some cases, this could lead to thrashing the Virtual Memory system. A blog entry from Ridiculous Fish inspired me to re-design the decoder.
Instead of storing decoded file parts, the new program stores file decoding states. It scans each argument up to the point that it finds encoded data. If the attachment is part of a single message, it decodes it immediately. If the attachment is spread over multiple messages, it saves the current state of the decoder (attachment attributes, file position) in an STL map and closes the file. There is a separate STL map for each encoding method (uuencode, MIME, yEnc) because they specify multi-part files differently. After all arguments have been scanned, the program walks through the part maps, discarding incomplete parts by default, and decodes each attachment in sequence. The decoded data is immediately written to a file, so there is never more than one part's data in the VM at any time. Both the input and output files are marked with the F_NOCACHE call from Fish's blog. Any input file from which something was decoded will be deleted by default.
Anyway, the decoder is mostly useful in my particular setup, but I thought I would post the code as another example of memory cache optimization. Also, the collection of frozen input states reminds me of some Lisp closure tricks, so here is another vote for the idea that learning one language (especially Lisp/Scheme) will improve your code in other languages.