Rust: impl Ord for bool: optimization

Created on 26 Nov 2019  路  3Comments  路  Source: rust-lang/rust

Currently, impl Ord for bool converts the bools to u8s and then compares them.

On the playground,

pub fn using_ord(x: bool, y: bool) -> Ordering {
    x.cmp(&y)
}

compiles to

playground::using_ord: # @playground::using_ord
# %bb.0:
    movl    %edi, %ecx
    xorl    %esi, %ecx
    testl   %esi, %esi
    movl    $255, %eax
    cmovel  %ecx, %eax
    testl   %edi, %edi
    cmovnel %ecx, %eax
                                        # kill: def $al killed $al killed $eax
    retq
                                        # -- End function

A much shorter (in instruction count) and almost certainly faster version taking advantage of the fact that orderings are represented by i8 values -1, 0, and 1, is:

pub fn minus_transmute(x: bool, y: bool) -> Ordering {
    unsafe { std::mem::transmute(x as i8 - y as i8) }
}

which on the playground compiles to

playground::minus_transmute: # @playground::minus_transmute
# %bb.0:
    movl    %edi, %eax
    subb    %sil, %al
                                        # kill: def $al killed $al killed $eax
    retq
                                        # -- End function
C-enhancement I-slow T-libs

Most helpful comment

FWIW, you get identical codegen with a match statement (+ an unreachable_unchecked), which I find slightly more readable than the transmute:

pub fn minus_match(x: bool, y: bool) -> Ordering {
    match x as i8 - y as i8 {
        -1 => Ordering::Less,
        0 => Ordering::Equal,
        1 => Ordering::Greater,
        _ => unsafe { std::hint::unreachable_unchecked() }
    }
}

All 3 comments

FWIW, you get identical codegen with a match statement (+ an unreachable_unchecked), which I find slightly more readable than the transmute:

pub fn minus_match(x: bool, y: bool) -> Ordering {
    match x as i8 - y as i8 {
        -1 => Ordering::Less,
        0 => Ordering::Equal,
        1 => Ordering::Greater,
        _ => unsafe { std::hint::unreachable_unchecked() }
    }
}

Fair enough; that does seem like it relies on less assumptions about "the outside", too.

I would like to work on this issue unless somebody else already started working on it.

Was this page helpful?
0 / 5 - 0 ratings