Cheap Skinny Ports
How we're using open source software tailored to our needs, keeping runtimes fast, codebases unified, and still being a good steward to the open source community.
I’m building software to emulate Excel’s calculation engine.
From the beginning, I knew this would require an enormous volume of test cases - authoritative pairs of workbooks and cell values (inputs), and the values calculated by Excel for each (outputs). To capture these, I created a “harness” for Excel on windows - you hand it an XLSX file, and it produces a test case in the format that anchors my Excel-emulating calculation engine.
The immediate problem I ran into was throughput. I needed to generate many test cases, but each step was monstrously slow: opening an excel spreadsheet in Windows, mutating some of its values through python libraries, saving it, and then parsing relevant features from the resulting file (Excel stores the calculated cell values in the saved XLSX file format). With off-the-shelf libraries, it took longer to run the harness infrastructure than it took to open the Excel spreadsheet and do the calculation. I was giving away over half of the computational energy to overhead - CPU cycles that then couldn’t be spent on the actual Excel calculations I was interested in.
Though I made a variety of algorithmic improvements to improve multiprocessing and reduce COM contention, the largest dent I made in processing time (reducing the overhead time from over a minute to under 100ms) was through what I’m calling “Skinny Ports”.
First some definitions: a “clone” of a library is when you make a copy of the library and adapt it for your purposes, a “port” is similar, but the copy is often written in a different language than the original, while preserving its core logic. Porting and cloning code is now simple because AI systems make both creating and verifying a port relatively straightforward, and reduce the burden of managing clones. A “skinny port” is a port where the goal of the port is not comprehensive coverage/equivalence, but a port with the ambition of serving only a small set of needs, and doing it well. In my calculation engine, I’ve made about seven “skinny ports” and “skinny clones” of other libraries, and through them have radically improved the performance at multiple layers.
To make this concrete, I’ll tell you a bit about my experience of porting openpyxl. Openpyxl is a library in Python that encodes how to read and write Excel file formats, like XLSX. This might sound simple, but these file formats are intricate and nuanced. The team behind openpyxl has (over the course of 15+ years) found all of the little bugs and quirks of the format. Thus, rather than implementing this from scratch, in the first version of my harness, I used openpyxl to capture the results of an Excel file once saved, since the saved version caches the computed formula values. This worked, but it was painfully slow, and I quickly realized that to produce the volume of cases I wanted to, I needed something faster. After testing out a few openpyxl competitors in other languages, I found each to have clear gaps in functionality that would prevent their adoption, so I decided to port openpyxl to Go (because the rest of my harness code is also in Go). I asked a sophisticated AI agent to make the port, which it did in short order, after we co-designed and built a harness for testing equivalency between the original openpyxl code and the ported Go code. This port consumed many tokens, but very little energy from me.
Out of the box, the Go port was more than 100x faster than its python equivalent, and with some fine tuning/performance tweaks, that number went far above 1000x. Though the speed is an obvious advantage, and the reason I started the port, the flexibility I got from owning my dependencies in this way turned out to be dramatically more valuable than the speed alone:
1. Personalized Interfaces
A general purpose library has to design its interfaces for a broad range of consumers, and it has to balance speed, simplicity, and comprehensiveness. A personalized port allows you to fine tune the interfaces for your specific use cases.
For example, in my openpyxl port, I ended up creating a set of streaming APIs to allow lower RAM usage over large spreadsheets, something that the python library didn’t implement.
2. Language Unification
To move fast, you often want to farm out complicated logic to well established libraries. However, it’s often the case that the best libraries for A and B and C are in different languages. Ports allow you to port each of your dependent libraries into the language you want to work in, often achieving type safety and simplifying the call structure.
For example, in my first version of the Excel harness, I had a smorgasbord of libraries and processes and binaries that were all trying to talk to each other. It worked, but it was a nightmare to reason about, and context about failures was spread across multiple different tools. By unifying them into a single binary, in a single language, I was able to get unified error reporting, and eliminate a wide array of expensive (and slow) cross-process communication.
3. Personalized Optimization
Porting a library from a slower language to a faster one will often provide significant performance benefits, even if all of the logic is equivalent. But the bigger opportunity is that once ported, you’re able to push on optimizing the performance of the ported library to suit the specifics of your use - something that the maintainer of a generic library with many constituent users can’t prioritize
For example, the python version of openpyxl did a bunch of processing on first ‘opening’ an excel file that wasn’t necessary in many of the cases I care about. By porting it, I got to refactor that code so that it only does the computation it strictly needs to to accomplish the aims I have.
4. Supply Chain Derisking
Reliance on open source libraries is a double edged sword. On the one hand, you get the benefit of reusing someone’s intellectual labor. On the other, you have to trust that the author(s) have not embedded anything malicious in their code, and trust that they will not do so in the future. A one-time port is a layer at which you can validate the security of the code, and remove dependencies and behavior that is riskier or broader than you want to maintain.
For example, in the openpyxl port, I was able to prune out certain dependencies, like Pillow, because I didn’t require the image functionality that Pillow enables within openpyxl.
Implications
I think this approach is a really robust one from a development perspective, but I worry about what it means for the future of the open source community. Open source is a massive common good, and dynamics that make it cheaper than ever to copy and modify reduce much of the incentive to be a good steward of it.
To that end, I made two decisions about how to handle my ports to balance this newfound capability with the ethos that makes it possible.
- First, when I find bugs or functionality missing from openpyxl, in addition to implementing it in my port, I’m going to offer the changes upstream into the original Python repo.
- Second, I decided not to publish my port, since I think having a faster equivalent might draw attention away from the more carefully maintained, higher quality project (openpyxl).