字节格式的 longs 的快速(呃)比较?

Fast(er) comparison of longs in byte format?

我有一个包含 byte[] 键的键值存储。其中一些键将用于多头(多头本身,还有 Localdate 和 LocalTime 实例)。

我有一个非常干净的比较器,使用标准 Java 和番石榴:

    @Override
    public int compare(byte[] left, byte[] right) {
        long leftLong = Longs.fromByteArray(left);
        long rightLong = Longs.fromByteArray(right);
        return Long.compare(leftLong, rightLong);
    }

但它比我预期的要慢。排序 100,000 个长整型需要 100 毫秒,而排序 100,000 个整型需要 6 毫秒。

有没有更快的方法来比较两个长整型,也许是通过避免 int 转换?

(您可能想知道它是否真的需要更快。如果可能的话是的,因为它会在每次搜索、扫描、插入和删除 long、日期等到存储中时调用。)

我对花费这么长时间并不感到惊讶:分配和销毁一万亿个小对象的订单似乎很费力。为什么不直接比较数组本身?

public int compare(byte[] left, byte[] right) {
    int cmp = 0;
    for(int i = 0; i < 8 && cmp == 0; i++) { 
       cmp = (i == 0 || (left[i] >= 0 == right[i] >= 0)) ? left[i] - right[i] : right[i] - left[i]           
    }
    return cmp;
}

这是另一种变体。它与原来的类似,但在单个循环中有效地完成了两个字节到长的转换。这提高了大约 20%-30% 的性能。 @Dima 的版本更快。

    public static int compareLongs(byte[] left, byte[] right) {
        long leftLong = 0;
        long rightLong = 0;
        for (int i = 0; i < 8; i++) {
            leftLong <<= 8;
            rightLong <<= 8;
            leftLong |= (left[i] & 0xFF);
            rightLong|= (right[i] & 0xFF);
        }
        return Long.compare(leftLong, rightLong);
    }