The headline promise ("without losses") is marketing gloss. The paper measures CPU performance. It does not measure migration cost or savings. The useful part is a clear, data-backed rule of thumb: start with Clang/LLVM, then benchmark your own workload before you commit.
The problem: two toolchains, one choice
Plenty of Python's foundations are C and C++. NumPy and CPython are, and so is a lot of in-house Windows software. Porting that code to ARM64 means more than waiting for dependencies. You also have to pick a compiler. On Windows on Arm, the two realistic options are MSVC and Clang/LLVM. Linaro's porting guidance agrees: the two realistic choices for Windows on Arm are MSVC and Clang.
Khmyznikov warns that swapping compilers is not a one-flag change in a large codebase. In the interview he says Clang still lacks some MSVC intrinsics, and that link-time optimization and exception handling need extra work. The paper adds that clang-cl was designed as a drop-in replacement for cl.exe. In practice, though, it says complex Windows projects bring friction. It names side-by-side manifests, debug symbol generation and structured exception handling (SEH) as pain points.
The test setup
The paper benchmarks native ARM64 builds on two Qualcomm-based machines:
- Older platform: Microsoft's Volterra / Windows Dev Kit 2023, with a Snapdragon 8cx Gen 3 (eight Kryo cores based on Cortex-X1/A78).
- Newer platform: Surface Laptop 15 with a Snapdragon X Elite X1E80100 (custom Oryon cores).
The toolchains were MSVC v14.51 (Visual Studio 2026 Preview) and LLVM 22.1.1 in clang-cl mode. Both used link-time optimization (-flto for LLVM, /GL /LTCG for MSVC).
Four open-source projects stood in for different workload types:
- LAME: an MP3 encoder, as a mixed DSP workload.
- NumPy: square-root and sorting operations.
- x264: an H.264 video encoder.
- CPython: the Python interpreter, using 15 CPU-bound subtests.
The run counts were 20 LAME encodes, 50 NumPy iterations, three x264 passes and 40 runs of each CPython subtest. Processes were pinned to specific cores, with warm-up runs before measurement. The CPython headline number is a geometric mean across the subtests.
The results
| Test | Kryo: MSVC vs. LLVM | Oryon: MSVC vs. LLVM |
|---|---|---|
| LAME encode time (lower is better) | 1.104 s vs. 0.810 s | 0.574 s vs. 0.402 s |
| NumPy sqrt time (lower is better) | 4.322 ms vs. 4.209 ms | 0.629 ms vs. 2.113 ms |
| NumPy sort time (lower is better) | 82.28 ms vs. 42.66 ms | 62.58 ms vs. 25.76 ms |
| x264 throughput in fps (higher is better) | 3.74 vs. 4.48 | 8.18 vs. 9.97 |
| CPython geometric mean (lower is better) | 78.20 ms vs. 59.29 ms | 49.05 ms vs. 32.11 ms |
- LAME: LLVM was about 26.6% faster on Kryo and 30% faster on Oryon.
- x264: LLVM's throughput gain was roughly 19.7% on Kryo and 21.8% on Oryon.
- CPython: LLVM won 14 of the 15 subtests. The exception was
pidigits, which does arbitrary-precision arithmetic. So LLVM did not win everything even in this suite. - NumPy sort: LLVM was nearly twice as fast on Kryo and more than twice as fast on Oryon.
The exception that matters
The NumPy square-root test is the outlier. On Kryo the two compilers were effectively tied, and the paper puts the gap within the error margin. On Oryon, MSVC finished in 0.629 ms against LLVM's 2.113 ms, which is 3.4 times faster. The paper attributes this to microarchitecture-specific behavior in MSVC's code generator. Treat that as the author's interpretation, not something the benchmark isolates.
This is one isolated kernel. It does not show that MSVC is better for math software in general. What it does show is that you can't assume the winner from the previous chip generation will still win on the next one. The same test on Kryo would have told you the compilers were equivalent.
Binary size is not one story
The LAME build also illustrates that faster code doesn't mean bigger code. The final executables were similar in size, at 513 KB for MSVC and 535 KB for LLVM. The static libraries differed sharply, at 4.0 MB for MSVC against 1.3 MB for LLVM. The paper attributes the MSVC library bloat to how intermediate representation is preserved. That is a result for this one project and build configuration, not a general rule.
Outside evidence points the same way
Other projects have already moved. A scikit-learn proposal says NumPy now ships win_arm64 wheels built with clang-cl. It also cites a CPython issue that traces ARM64 Windows slowness to MSVC's weaker ARM64 auto-vectorisation. That is a community proposal rather than a benchmark, but it matches the paper's direction. In llama.cpp's Windows ARM64 work, one contributor's profile showed LLVM/Clang ahead of MSVC on CPU-backend inference. A later pull request notes that MSVC builds couldn't enable all the Arm intrinsics Clang could.
What the study does not cover
The limits matter for planning:
- All the benchmarks are CPU-bound. GPU and NPU workloads were not tested.
- ARM64EC, the hybrid ABI that mixes x64 and ARM64 code in one process, was out of scope. The paper itself calls it important for real migrations of large systems.
- Profile-guided optimization was not compared.
- The measurements come from two specific devices on specific Windows builds. They are not a ranking of all Arm PCs.
- Compiler versions change generated code, so the numbers could shift with newer MSVC or LLVM releases.
For these reasons, Khmyznikov's own statement of "platform maturity" is an assessment, not something the benchmarks prove. The data show that both compilers produce working native ARM64 code and that performance differs by task. They say nothing about cost, labor or the readiness of any particular company's dependencies.
A practical migration approach
The interview and the paper together support a sequence like this:
- Inventory dependencies first. In the interview, Khmyznikov says browsers, messengers and mainstream office apps already run on Arm. He puts the risk in in-house tools and the scientific stack.
- Pilot on a few Arm machines with real workloads. He argues this will surface problems faster than any compatibility chart.
- Port the hottest code first. Heavily loaded internal components can go native while the rest runs under Prism x64 emulation until vendors ship Arm builds.
- Default to Clang/LLVM for media, sorting, and interpreter-style code, where the paper found consistent wins.
- Benchmark math-heavy kernels on the actual target chip before choosing, especially for newer Qualcomm silicon.
- Budget for integration work if you move off MSVC. That means intrinsics, LTO, exception handling and build system changes.
The emulation backdrop
The interview also covers the wider context. By Khmyznikov's account, Python on Windows on Arm often runs unnoticed as x64 under Prism emulation. He cites an earlier December 2024 study in which native Python ran almost 23% faster on average than emulated x64 Python. He also reports that about 96% of the top 1,000 Python packages support Windows on Arm natively or don't depend on the processor. These figures come from the interview's account of his own work, and I haven't independently checked them.
Bottom line
The paper's takeaway is modest and useful. Clang/LLVM is a sensible default for native ARM64 builds on Windows. NumPy's square-root result on Oryon shows why a default isn't a decision. Profile your own code on the hardware you'll ship before you rewrite build systems around either compiler.
References
- How Can a Company Move to Arm Without Losses? Gleb Khmyznikov on Where to Start the Switch - Analytics Insight Analytics Insight · 2026-10-12T08:50:00+00:00
- So, you want to port your C/C++ project to Windows on Arm? linaro.org
- (PDF) Comparative Analysis of MSVC and Clang/LLVM Compilation on Windows on Arm researchgate.net