Developing on a 2019 Mac Pro


There's been a lot of discussion about the 2019 Mac Pro and various assertions that it's over-designed, overpriced, or underpowered. Since I decided to replace my venerable 2013 Mac Pro[^1] with a 2019 Mac Pro, I figured I'd write up my experience with the device as a developer.

The Codebase

So that people have context for what the codebase is that I'm talking about here, I currently ship 3 "products":

Cartographica is by far and away the largest of these three projects. Besides over 250K lines that I have written over the years (CLOC lines of code, not counting whitespace or comments), there are another approximately 1.2M lines of third-party code[^2] that gets compiled every time I do a Clean and Build.

LoadMyTracks is much smaller, about 44K lines of code by me (some shared with Cartographica, but for the purposes of this article, I'm interested in describing what's compiled) and about 37K lines of third-party code.

CartoMobile is in the middle, with approximately 134K lines written mostly by me (the remainder of the ClueTrust code was written by a contractor early on in CartoMobile's life) and about 380K lines of third-party code.

Beyond the code, we have a fair number of tests that run in the system as well. Cartographica has on the order of 3500, CartoMobile has around 700, and LoadMyTracks around 150. These are each mostly unit tests, with some integration tests as well. The UI tests (a combination of manual and automated) are not included here, as they don't run automatically in the CI environment.

Build Environment

I try to keep on the latest build environments wherever possible, which means a fair amount of work maintaining the code base (and removing deprecations). Thus, the build environment is Xcode 11.3 as of the arrival of the 2019 Mac Pro. I'm using Xcode's parallel testing, so it's not out of the ordinary for the 2019 Mac Pro to have 8 or 10 copies of Cartographica running for the in-process tests and a similar number of xctest instances running during the stand-alone tests.

For Continuous Integration (CI), I run Jenkins on a set of Mac Minis, with most of the build work being done by a 2018 Mac Mini. CI builds are run using fastlane and Jenkins pipelines.

Before and after

Cartographica

Now that I've set out the environment and the challenge, let's see how the Mac Pro did with it. Clean building on the 2013 Mac Pro (6-core) takes 358s, or close to 6 minutes. Clean building on the 2019 Mac Pro (16-core) takes 82s. For the record, building in the Xcode GUI directly on the 8-core 2018 Mac Mini takes 177s.

The tests themselves are a different matter. The Mac Mini is still beating the 2019 by about 18s of wallclock time (131s vs 110s), mostly owing to 2 single-threaded tests (run in parallel) that take 51s on the Mac Pro and only 31s on the Mac Mini. I'm tracking this issue down, but in this case, the Mac Mini is running 10.14 still and the 2019 (like it's predecessor) is running 10.15.2. Since these long-running tests involve spawning a subprocess to run a shell script which executes a unix-level executable approximately 400 times, I'm guessing this is related to a difference in the shell execution. For reference, the 2013 Mac Pro took over 180s to run these tests. Interestingly, the MacBook Pro (running 10.15.2) runs the tests similarly to the Mac Mini, taking 35s to run the long shell-script based test.

Machine Build Time Test Time Scripted Test
2019 Mac Pro (16 core Xeon) 82s 131s 51s
2019 MacBook Pro (8 core i9) 169s 116s 35s
2018 Mac Mini (6 core i7) 177s 110s 31s
2013 Mac Pro (6 core Xeon) 358s 223s >180s

LoadMyTracks

Differences on LoadMyTracks were much smaller, which I assume is because the code base is so much smaller. The test times are almost identical.

Machine Build Time Test Time
2019 Mac Pro (16 core Xeon) 16.5s 3s
2019 MacBook Pro (8 core i9) 18.8s 3s
2018 Mac Mini (6 core i7) 15.5s 3s
2013 Mac Pro (6 core Xeon) 43.1s 4s

CartoMobile

CartoMobile's larger codebase (thus more amenable to compiling in parallel), results in another significant win for the 2019 Mac Pro over the 2013 (and the Macbook Pro this time). As with Cartographica, the Mac Mini is a close 3rd behind the 2019 MacBook Pro

Machine Build Time
2019 Mac Pro (16 core Xeon) 20.8s
2019 MacBook Pro (8 core i9) 32.1s
2018 Mac Mini (6 core i7) 47.2s
2013 Mac Pro (6 core Xeon) 48.5s

Conclusion

Not surprisingly, it looks like the larger the codebase, and the more amenable to being built or tested in parallel, the better the 2019 Mac Pro runs. This was pretty much the case with the previous Mac Pro as well, when compared to the Mac Minis and laptops at the time.

I don't have an iMac Pro to perform these tests on, but based on the significant performance improvements over the 6- and 8-core machines, I expect I'd want the 14- or 18-core iMac Pro to try and reach the same performance. However, those two machines are clocked at 2.5 and 2.3Ghz respectively, which is significantly lower than the 2019 Mac Pro 16-core's 3.2Ghz.

Assuming that the 18-core would be sufficient, a similarly configured machine (2TB NVMe SSD, default video card, 64GB of RAM) would run me $8278 list. The 2019 Mac Pro configuration I purchased, along with 64GB of 3rd Party RAM and LG 5K display, listed at $8799 + $1299 + $442 = $10,540. It's definitely $2,262 more, although if I were purchasing the iMac, I'd probably upgrade the video card, since I don't have any option to do it later (reducing the difference by $700). In addition, if it hadn't been for the strange spot that the 2013 Mac Pro existed in (Thunderbolt 2 not quite having enough bandwidth for 5K 60Hz on a single cable), I wouldn't need to replace my Dell 5K monitor that I'd used with it for the last 5 years, which would drop the difference by another $1299.

With that said, for compiling my main App, the processor speed reduction of close to 30% might be an issue.

In the end, the value proposition of a Mac Pro vs. competing platforms is a judgement call for anyone who is considering it. The combination of the flexibility (I changed graphics cards and expanded RAM in my previous "cheese grater" models) and the external monitor to me makes enough of a difference to come down on the side of the Mac Pro. Assuming that Apple keeps up with it, I may end up replacing the computer and keeping the components, such as upgraded graphics cards and maybe RAM. If they don't keep up with the upgrades, the replaceable CPU is likely to result in opportunities to improve performance, as had been done with previous models containing replaceable CPUs.

[^1]: Seriously, I was pretty happy with it, despite the clear lack of upgradability and limits to expansion.

[^2]: Shout out here to the most significant third-party code that we use: GDAL, Sparkle, and Proj.