New week, new Rust! What are you folks up to?
Started playing with some ideas in
elastic to support both a sync and async client without forking too much code. I’ll probably iterate on that a few times before settling on a particular approach and am interested in how other client libraries are approaching the problem.
I’m also cleaning up a little compiler plugin I’ve been using in apps for automatically deriving traits for common smart pointers and closures. It started life as a macro and I’ll probably retire it one day when we’ve got trait aliases or decide to structure my apps differently. But I still find it handy sometimes. I’ll try release that this week.
I’ve got a tracking issue for the
same-file libz blitz evaluation to open this evening. There are a few active evaluations that need your input, so please go check them out if you get a chance:
Working on my RustFest Zurich proposal after my mentor gave me feedback!
Incidentally if you didn’t know the call for proposals deadline has now been extended to the end of July!
So there’s still time to submit you proposals, or ask for a mentor (in my case).
p.s. Thank you to all the people who have volunteered to be mentors!
Interfacing /proc/meminfo for sampling turned out to be much easier than /proc/stat: the internal structure of that file is much more regular (mostly a list of named data volumes with a few raw event counters here and there), so one can avoid the code complexity and run-time overhead associated with switching between different parsers from one line to another.
Add to that the nice suggestion that someone gave me last week of using bytesize for data volume storage, and there was very little custom work to do in order to get a basic implementation working.
On the other hand, this simple structure means that performance is basically bound by the basic text parsing primitives in use (line splitter, word splitter…), so parsing this file fast (say, 2x faster than the kernel produces it, as I manage with other files) was a more interesting challenge. And as too often when it comes to performance optimization, I just couldn’t resist the lure of it even though it truly did not matter so much.
Since the code was mostly bottlenecked by memory accesses in the lines and word splitters, as can be expected from a straightforward text parser with little high-level logic, a promising avenue was to avoid wastefully parsing the input twice, once to split lines and another time to split every line into words. So I tried to build an iterator that can split both lines and space-separated words in a single pass through the input text.
The outcome can be best summarized as “do not do this at home unless you really have a performance problem”. It took me a while to get it to work at all, the interface is less elegant than the original dual iterator version, and when I finally got an initial implementation running on real meminfo data, it was no faster than the original code because all the iterator fiddling needed for communication between the line splitter and the word splitter ate as much CPU time as I was saving by avoiding two passes through the input data.
But by using more careful iteration patterns (e.g. itertools::PutBack instead of repeatedly peek()-ing), I got it 15% faster than the original. At this point, the code is still bottlenecked by line/word splitting, and I have some more ideas to try out before declaring myself satisfied (notably building a customized version of CharIndices to avoid outputting the current char index on every iteration when I, in fact, only need it when specific characters are reached). But reaching the ideal case of 50% of the original dual-iterator version is probably not a realistic goal: what you gain by not processing the same text twice, you lose by adding more complex logic on every character, which also consumes CPU time.
Mostly a lot of summer fun, a little bit of work on
uom (type-safe zero-cost dimensional analysis) trying to figure out how to share some code while working on thermodynamic temperature and temperature interval.
Please, contact me if you want to help!
I just closed issues #10, the task to implement an ambient-occlusion integrator. Should match the C++ side and bring up the render time to an observable level. Having a Cornell Box scene now screams for starting to work on global illumination (GI), and I might start on doing that, but I’m abroad in LA (for SIGGRAPH starting on Sunday) and might not be able to spend a lot of time on it.
Started in on my Piet interpreter again. I wrote it in Ruby originally and I’m now figuring out the best way to convert it to Rust.