2个整数与另外2个整数的有效比较
Efficient comparison of 2 integers against another 2
我有一段用于比较的代码,它位于被调用数百万次的热路径中。基准测试后,该段代码是优化的候选者。
基本上,我有 2 个整数 c
和 m
。比较两个对象涉及首先检查 c
然后如果 c
两边相等,然后比较由它们的 m
值决定。
c
只能在 [0-100]
范围内
m
只能在 [0-200]
范围内
伪代码
if this.c < other.c return -1; // Or any negative number
if this.c > other.c return 1; // Or any positive number
// Both objects have equal 'c' value
if this.m < other.m return -1; // Or any negative number
if this.m > other.m return 1; // Or any positive number
// Both 'c' and 'm' are equal
return 0;
下面的C#代码是我目前的
int CompareTo(Obj other)
=> _c < other._c || (_c == other._c && _m < other._m)
? -1
: _c == other._c && _m == other._m
? 0
: 1;
我想知道这是否可以进一步优化,或许可以通过位操作?
谢谢
比 dxiv 的版本略短,但基于相同的想法:
(this.m - other.m) + ((this.c - other.c) << 8)
所以我们首先比较m
,然后通过c
的比较覆盖它,利用m
的有限范围。
c
can only be in the range [0-100]
m
can only be in the range [0-200]
给定范围,每个 c, m
都适合一个(无符号)字节,因此它们可以一起打包成一个整数 cm = c * 256 + m
,或仅使用按位操作 cm = (c << 8) | m
.
由于只有比较函数的符号很重要(如评论中所述),因此可以通过直接减法来比较两个这样的整数。
int CompareTo(Obj other) => ((_c << 8) | _m) - ((other._c << 8) | other._m)
以上是无分支的,仅使用 bitwise/arithmetic 运算符,因此对于大多数 c, m
值的分布,它应该能够很好地对抗嵌套比较。
我有一段用于比较的代码,它位于被调用数百万次的热路径中。基准测试后,该段代码是优化的候选者。
基本上,我有 2 个整数 c
和 m
。比较两个对象涉及首先检查 c
然后如果 c
两边相等,然后比较由它们的 m
值决定。
c
只能在 [0-100]
m
只能在 [0-200]
伪代码
if this.c < other.c return -1; // Or any negative number
if this.c > other.c return 1; // Or any positive number
// Both objects have equal 'c' value
if this.m < other.m return -1; // Or any negative number
if this.m > other.m return 1; // Or any positive number
// Both 'c' and 'm' are equal
return 0;
下面的C#代码是我目前的
int CompareTo(Obj other)
=> _c < other._c || (_c == other._c && _m < other._m)
? -1
: _c == other._c && _m == other._m
? 0
: 1;
我想知道这是否可以进一步优化,或许可以通过位操作?
谢谢
比 dxiv 的版本略短,但基于相同的想法:
(this.m - other.m) + ((this.c - other.c) << 8)
所以我们首先比较m
,然后通过c
的比较覆盖它,利用m
的有限范围。
c
can only be in the range[0-100]
m
can only be in the range[0-200]
给定范围,每个 c, m
都适合一个(无符号)字节,因此它们可以一起打包成一个整数 cm = c * 256 + m
,或仅使用按位操作 cm = (c << 8) | m
.
由于只有比较函数的符号很重要(如评论中所述),因此可以通过直接减法来比较两个这样的整数。
int CompareTo(Obj other) => ((_c << 8) | _m) - ((other._c << 8) | other._m)
以上是无分支的,仅使用 bitwise/arithmetic 运算符,因此对于大多数 c, m
值的分布,它应该能够很好地对抗嵌套比较。