# Micro-optimizations in .NET (x86/x64)

First of all, I want to thank the developers of **SharpLab** for providing such an amazing tool to explore the machine code generated by the .NET JIT compiler. All examples in this post are based on **.NET 7/8**.

### Conversion from Boolean to Integer

This is a popular and straightforward example of a micro-optimization. Suppose we want to convert a `bool` to an `int`: `1` for `true` and `0` for `false`.

The most obvious implementation uses a ternary operator:

```csharp
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int ConvertBooleanToInt(bool value)
{
    return value ? 1 : 0;
}
```

If you examine the generated machine code, you will see a **conditional branch** (`jne`):

```csharp
; Examples.ConvertBooleanToInt(Boolean)
    L0000: test cl, cl
    L0002: jne short L0007
    L0004: xor eax, eax     ; result = 0
    L0006: ret
    L0007: mov eax, 1       ; result = 1
    L000c: ret
```

Conditional branches can be expensive due to potential **branch mispredictions**. However, in the CLI, a `bool` is physically stored as a 1-byte value (`0` for false, `1` for true). We can exploit this by reinterpreting the memory directly.

### Using Unsafe Pointers

You can treat the address of the boolean as a pointer to a byte. *Note: In your original snippet,* `return (byte*)&value` would return the memory address. To get the value, we must dereference it:

```csharp
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe int ConvertBooleanToIntUnsafe(bool value) 
{
    return *(byte*)&value;
}
```

### The Modern Way: [Unsafe.As](http://Unsafe.As)

A cleaner way to achieve the same result without manual pointer manipulation is using the `Unsafe` class. This produces the same optimized machine code:

```csharp
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int ConvertBooleanToIntOptimized(bool value) 
{
    return Unsafe.As<bool, byte>(ref value);
}
```

**Generated Machine Code:**

```csharp
; Examples.ConvertBooleanToIntOptimized(Boolean)
    L0000: movzx eax, cl
    L0003: ret
```

The JIT compiler now uses a single `movzx` (move with zero-extend) instruction. This completely eliminates the branch, making the code deterministic and faster in tight loops.

### Update: Improvements in .NET 9

It is worth noting that starting with **.NET 9**, the JIT compiler has become much smarter at handling this specific pattern. The community and the Microsoft team implemented an optimization that recognizes the ternary conversion `value ? 1 : 0` and automatically transforms it into a branchless `movzx` instruction.

This means that in .NET 9, the "obvious" version and the "optimized" version now produce identical, high-performance machine code:

```csharp
; Examples.ConvertBooleanToInt(Boolean) in .NET 9
    L0000: movzx eax, cl
    L0003: ret
```

### Should you still use [`Unsafe.As`](http://Unsafe.As)?

While .NET 9 handles the simple `1 : 0` case, [`Unsafe.As`](http://Unsafe.As) or pointer manipulation remains a valuable tool for:

1. **Older Runtime Versions:** If your library supports .NET 6, 7, or 8.
    
2. **Complex Logic:** When the mapping isn't a simple `1` or `0`, or when you are reinterpreting `bool` as part of a larger struct layout.
    
3. **Educational purposes:** Understanding how data is represented in memory is key to writing high-performance code.
