The excitement around Apple’s new M1 chip is everywhere. I bought a MacBook Air 16 GB M1 to see how viable it is as a main development machine — here’s an early report after a week of testing.
Xcode
Xcode runs FAST on the M1. Compiling the PSPDFKit PDF SDK (debug, arm64) can almost compete with the fastest Intel-based MacBook Pro Apple offers (to date), with 8:49 minutes vs. 7:31 minutes. For comparison, my Hackintosh builds the same in less than 5 minutes.
One can’t overstate how impressive this is for a fanless machine. Apple’s last experiment with fanless MacBooks was the 12-inch version from 2017, which builds the same project in 41 minutes.
Our tests mostly ran just fine, although I found a bug specific to arm64, which we missed before, as we don’t run our tests on actual hardware on CI. Moving the simulator to the same architecture as shipping devices will be beneficial and will help find more bugs.
Testing iOS below 14 is problematic. It seems WebKit crashes in a memory allocator, throwing EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
(Apple folks: FB8920323). Performance also seems really bad, with Xcode periodically freezing, and the whole system becoming so slow that the mouse cursor gets choppy. Some simulators even make problems on iOS 14; an example of this is iPad Air (4th generation), which still emulates Intel, so try to avoid that one.
We were extremely excited to be moving our CI to Mac minis with the M1 chip and are waiting on MacStadium to release devices. However, it seems we’ll have to restrict tests to iOS 14 for that to work. With our current schedule, we plan to drop iOS 12 in Q3 2021 and iOS 13 in Q3 2022, so it’ll be a while before we can fully move to Apple Silicon.
There is a chance that Apple fixes these issues, but it’s not something to count on — given that this only affects older versions of iOS, the problem will at some point just “go away.”
Update: We’re working around the WebKit crashes for now via detecting Rosetta 2 translation at runtime and simply skipping the tests where WebKit is used. This isn’t great, but luckily we’re not using WebKit a lot in our current project. See my gist for details. Performance seems acceptable if you restrict parallel testing to, at most, two instances — otherwise, the system simply runs out of RAM and swapping is really slow.
Update 2: I’ve heard that the choppy mouse cursor is an Xcode/Simulator bug, and it’s currently being worked on. As a workaround, ensure at least one Simulator window is onscreen and visible.
Update 3: Great news! The WebKit crash when running on Rosetta 2 will be resolved with a future update in Big Sur.
Update 4 (May 2021): This is now fixed with Xcode 12.5 and macOS 11.3.
Docker
We use Docker to automate our website and load environments for our Web and Server PDF SDKs. Docker posted a status update blog post admitting that its client currently won’t work with Apple Silicon, but that the company is working on it. There are more hacky ways to use Apple’s Hypervisor to run Docker containers manually, but they need ARM-based containers.
I expect a solution that runs ARM-based containers in Q1 2021. We at PSPDFKit will have some work to do to add ARM support (something already on the roadmap), so this is only a transitional issue.
Virtualization and Windows
To test our Windows PDF SDK, most folks are using a VMware virtual machine with Windows 10 and Visual Studio. Currently, none of the Mac virtualization solutions support Apple Silicon. However, both VMware and Parallels are working on it. I don’t expect VirtualBox to be updated anytime soon.
I expect that, eventually, we’ll be able to run ARM-based Windows with commercial tooling. Various proofs of concept already exist, and performance seems extremely promising. Microsoft currently doesn’t sell ARM-based Windows, so getting a license will be interesting.
Windows 10 on ARM can emulate x86 applications, and Microsoft is working on x64 emulation, which is already rolling out in Insider builds. In a few months, it should be possible to develop and test our Windows SDK with Visual Studio on M1 with reasonable performance results.
Running older versions of macOS might be more problematic. We currently support macOS 10.14 with our AppKit PDF SDK, and macOS 10.15 with the Catalyst PDF SDK, both of which are OS releases that require testing. It remains to be seen if VMware or Parallels include a complete x64 emulation layer. This would likely be really slow, so I wouldn’t count on it.
Lastly, 16 GB RAM just isn’t a lot. When running parallel tests, the machine starts to heavily swap, and performance really goes down the drain. This will be even more problematic with virtual machines running. Future machines will offer 32 GB options to alleviate this issue.
Update: Check out How to run Windows 10 on ARM in QEMU with Hypervisor.framework patches on Apple Silicon Mac.
Android Studio
IntelliJ is working on porting the JetBrains Runtime to Apple Silicon. JetBrains apps currently work through Rosetta 2; however, building via Gradle is extremely slow. Gradle creates code at runtime, which seems like a particularly bad combination with the Rosetta 2 ahead-of-time translation logic.
I expect most issues will be solved by Q1 2021, but it’ll likely be some more time until all Java versions run great on ARM. A lot of effort has been put into loop unrolling and vectorization; not everything there is available on ARM just yet.
Update: Azul offers macOS JDKs for arm64 — also for Java 8.
Homebrew
Homebrew currently works via Rosetta 2. Prefix everything with arch -x86_64
and it’ll just work. It’s possible to install an additional (ARM-based) version of Homebrew under /opt/homebrew
and mix the setup, as more and more software is adding support for ARM.
This isn’t currently a problem (performance is good) and will eventually just work natively.
Applications
Most applications just work; Rosetta is barely noticeable. Larger apps take a longer initial performance hit (e.g. Microsoft Word takes around 20 seconds until everything is translated), but then the binaries are cached and subsequent runs are fast.
There’s the occasional app that can’t be translated and fails on startup (e.g. Beamer and the Google Drive Backup and Sync client), but this is rare. Some apps are confused about their place on disk and ask to be moved to the Applications directory, when really it’s just the translated binary that runs somewhere else. Most of these dialogs can be ignored. Some apps (e.g. Visual Studio Code) block auto updating, as the translated app location is read-only. However, in the case of VS Code, the Insider build is already updated to ARM and just works.
Electron-based apps are slow if they run on Rosetta. It seems the highly optimized V8 JavaScript compiler blocks ahead-of-time translation. The latest stable version of Electron (version 11) already fully supports Apple Silicon, and some companies — including Slack and 1Password — have updated their beta versions to run natively.
Google just shipped Chrome that runs on ARM, but there’s still quite a big performance gap between it and Apple Safari, which just flies on Apple Silicon.
Conclusion
The new M1 MacBooks are fast, beautiful, and silent, and the hype is absolutely justified. There’s still a lot to do on the software front to catch up, and the bugs around older iOS simulators are especially problematic.
All of that can be fixed in software, and the entire industry is currently working on making the experience better, so by next year — when Apple updates the 16-inch MacBook Pro and releases the next generation of its M chip line — it should be absolutely possible to use an M1 Mac as the main dev machine.
For the time being, the M1 will be my travel secondary laptop, and I’ll keep working on the 2,4 GHz 16-inch MacBook Pro with 32 GB RAM, which is just the faster machine. It’ll be much harder to accept the loud, always-on fans though, now that I know what soon will be possible.