Skip to content

Inefficiencies with IComparer<T>.Compare vs operators #81220

@stephentoub

Description

@stephentoub

Consider these three variations:

public static bool M1(int i, int j) => i <= j;
    
public static bool M2<T>(T i, T j) where T : IBinaryInteger<T> => i <= j;
    
public static bool M3(int i, int j) => Comparer<int>.Default.Compare(i, j) <= 0;

M1 and M2 (with T==int) both produce the nice:

    L0000: xor eax, eax
    L0002: cmp ecx, edx
    L0004: setle al
    L0007: ret

but M3 produces:

    L0000: cmp ecx, edx
    L0002: jl short L0013
    L0004: cmp ecx, edx
    L0006: jg short L001a
    L0008: xor eax, eax
    L000a: test eax, eax
    L000c: setle al
    L000f: movzx eax, al
    L0012: ret
    L0013: mov eax, 0xffffffff
    L0018: jmp short L000a
    L001a: mov eax, 1
    L001f: jmp short L000a

SharpLab

It'd be helpful if the JIT were able to unravel such an IComparer<T>.Default.Compare(...) followed by comparison to 0 into the equivalent of the direct operator usage.

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions