字节格式的 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);
}
我有一个包含 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);
}