Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 17323794 authored by Shai Barack's avatar Shai Barack
Browse files

Optimize Message comparison to be branchless.

Refactor `Message.compareMessages` to use a branchless formula based on `Long.signum` for `when` and `insertSeq` differences, maintaining the same comparison order.

This is based on a pprof of MessageQueuePerfTest which shows that most branch misses in our benchmarks come from Message#compareMessages.

https://pprof.corp.google.com/?id=1c73d480facfd5c483a5e72a5450e67d&metric=branch-misses&flamesearch=android.os.Message.compareMessages

This refactor produces smaller code:
https://godbolt.org/z/bvGh7aadG

And faster:
https://godbolt.org/z/Kf1v9qcYe

Flag: EXEMPT PURE_REFACTOR
Bug: 421623328
Change-Id: I4fb81774c00276747cca84ce070a4511a88501c5
parent 80166f36
Loading
Loading
Loading
Loading
+11 −18
Original line number Diff line number Diff line
@@ -622,24 +622,17 @@ public final class Message implements Parcelable {
    }

    /*package*/ static int compareMessages(@NonNull Message m1, @NonNull Message m2) {
        if (m1 == m2) {
            return 0;
        }

        // Primary queue order is by when.
        // Messages with an earlier when should come first in the queue.
        final long whenDiff = m1.when - m2.when;
        if (whenDiff > 0) return 1;
        if (whenDiff < 0) return -1;

        // Secondary queue order is by insert sequence.
        // If two messages were inserted with the same `when`, the one inserted
        // first should come first in the queue.
        final long insertSeqDiff = m1.insertSeq - m2.insertSeq;
        if (insertSeqDiff > 0) return 1;
        if (insertSeqDiff < 0) return -1;

        return 0;
        // Implement the comparison with branchless logic.
        final long when1 = m1.when;
        final long when2 = m2.when;
        final long insertSeq1 = m1.insertSeq;
        final long insertSeq2 = m2.insertSeq;
        final int whenSign = Long.signum(when1 - when2);
        final int insertSeqSign = Long.signum(insertSeq1 - insertSeq2);
        // whenSign takes precedence over insertSeqSign, so the formula below is such that
        // insertSeqSign
        // only matters as a tie-breaker if whenSign is 0.
        return whenSign * 2 + insertSeqSign;
    }

    @Override