You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Interlocked.Exchange<T>性能远低于Interlocked.CompareExchange<T>?

Why is Interlocked.Exchange slower than Interlocked.CompareExchange for reference types in .NET Core?

Great catch on this weird performance discrepancy! Let's break down exactly what's going on here, and tackle your questions one by one.

Key Observations to Ground This

First, let's recap the critical details from your benchmark and investigation that point us to the root cause:

  • For value types like int or long, both methods perform nearly identically, and disassemble directly to the CPU's xchg and cmpxchg instructions—exactly what you'd expect for low-level interlocked operations.
  • For reference types (like your string test), Interlocked.Exchange runs roughly three times slower than Interlocked.CompareExchange, and both show up as framework method calls in disassembly instead of direct CPU instructions.

The Real Cause: .NET Core Implementation Differences

This gap has nothing to do with CPU instruction performance—your value type test confirms that xchg and cmpxchg are roughly equivalent. Instead, it's all about how .NET Core implements these two methods for reference types:

The Interlocked.Exchange overload for reference types includes extra runtime checks and write barrier logic that the CompareExchange reference type overload skips. These additional operations add measurable overhead that shows up clearly in your benchmarks.

Your findings align with the issue you raised with the coreclr team, where they'll dig into whether this is an intentional design tradeoff or a missed optimization opportunity.

Should You Replace Exchange with CompareExchange?

Short answer: Only if the semantic behavior exactly matches what your code needs.

It's tempting to swap to the faster method, but don't forget—these two methods have fundamentally different purposes:

  • Interlocked.Exchange: Unconditionally swaps the reference with the new value, no questions asked, and returns the original value.
  • Interlocked.CompareExchange: Only swaps the reference if it matches the expected value you pass in; if not, it leaves things as-is and returns the current value.

If your code requires an unconditional swap, using CompareExchange (even with null as the expected value) will only work if you can guarantee the current reference is actually null. Otherwise, it'll fail to swap silently, introducing hard-to-debug concurrency bugs. Correctness always comes before performance.

Wrapping Up

This is a perfect example of how framework implementation details can create unexpected performance gaps, especially with low-level concurrency primitives. For reference types, the current .NET Core implementation creates this slowdown in Exchange, but it's not a reflection of what the CPU is capable of.

内容的提问来源于stack exchange,提问作者Shay Rojansky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:43:37