我有一个带有byte []键的键值存储。其中一些键将用于long(longs本身,也包括Localdate和LocalTime实例)。
我有一个很好的干净的比较器,使用标准的Java和Guava:
@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毫秒。
是否有更快的方法来比较两个long,可能是通过避免int转换?
(你可能想知道它是否真的需要更快。如果可能的话,因为每次搜索,扫描,插入和删除长,日期等都会被调用到商店。)
答案 0 :(得分:3)
我并不感到惊讶需要很长时间:分配和销毁万亿小物件的订单似乎很费力。为什么不直接比较数组?
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;
}
答案 1 :(得分:0)
这是另一种变体。它与原始类似,但在单个循环中有效地完成了两个字节到长的转换。这提高了约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);
}