How rewriting a C++/ObjC code base in Swift reduced it to 30%
In a recent Swift blog post, Graphing Calculator creator Ron Avitzur shared how his decision to completely rewrite his app in Swift allowed him to shrink his codebase to 30% of its original size, improving maintainability and readability without losing performance.
Graphing Calculator is an application for creating graphs of functions in two and three dimensions. Originally created in 1985, it was bundled by Apple with the original PowerPC computers, then became an independent product available for macOS, Windows and iOS. After 35 years of continuous development, the best way forward, according to Avitsur, was a complete rewrite, although that was still a major feat, requiring a lot of work.
Legacy code embodies decades of hard-learned lessons […]. Although a fresh start can be aesthetically pleasing, it creates a huge surface area for insects. In a typical point build, it’s easy to focus on testing new features. With a complete rewrite, everything is new.
The graphing calculator used a variety of different languages and stacks, including C++ and Objective C/C++, Lex and YACC, AppKit and UIKit, and OpenGL. This all turned into a cohesive Swift codebase using SwiftUI and Metal over 18 months with a reduction in line count from 152,000 lines to 29,000.
Less code means less to debug, less to read and understand, and that alone makes the port easier to maintain. Using SwiftUI, view controllers disappear altogether: a big win for declarative programming over imperative.
Among the main benefits of the rewrite, Avitsur mentions the reduction of boilerplate code, which made the logic and meaning of the code clearer; the use of value types in collection types, which simplified the reasoning about them; the brevity provided by type inference, enumerations, closures, and Swift concurrency.
The biggest challenge, however, was to maintain the same level of performance against a highly optimized codebase for over 30 years.
As Avitsur explains in a Twitter feed, the first port paid a 10x performance penalty. He could reduce it to 2x by disabling all Swift runtime checks and using vDSP for the innermost loops. One problem that remains, however, is the cost of automatic reference counting on tree traversalbecause the Swift compiler has no way of specifying that a given piece of code will not alter any reference count.
Overall, says Avitzur, Swift and SwiftUI delivered on their promise and opened up the ability to contribute portions of code as standalone Swift packages for mathematical composition, editing, numeric and symbolic computation, and representation. chart.