是否有另一种方法来测试 big.Int 是否为 0?
Is there another way of testing if a big.Int is 0?
我正在使用 big.Int
s,需要测试 0。现在,我正在使用 zero = big.NewInt(0)
和 Cmp(zero)==0
,它们工作正常,但我想知道是否有专门针对 0 的更快方法吗(我需要这个程序非常快)?
big.Int
exposes Int.Bits()
访问表示的原始字节,它是一个切片并且共享相同的底层数组:不复制返回的切片。所以它很快。它暴露于 “支持实现缺少的 low-level Int 功能”。
完美,正是我们想要的。
0。测试 0
big.Int
的文档还指出 “Int 的零值表示值 0”。因此,在零值(表示 0
)中,切片将为空(切片的零值为 nil
,nil
切片的长度为 0
)。我们可以简单地检查一下:
if len(i1.Bits()) == 0 {
}
另请注意,有一个 Int.BitLen()
函数返回此值,它还声明 “0 的位长度为 0”。所以我们也可以用这个:
if i1.BitLen() == 0 {
}
让我们对这些解决方案进行基准测试:
func BenchmarkCompare(b *testing.B) {
zero := big.NewInt(0)
i1 := big.NewInt(1)
i2 := big.NewInt(0)
for i := 0; i < b.N; i++ {
if i1.Cmp(zero) == 0 {
}
if i2.Cmp(zero) == 0 {
}
}
}
func BenchmarkBits(b *testing.B) {
i1 := big.NewInt(1)
i2 := big.NewInt(0)
for i := 0; i < b.N; i++ {
if len(i1.Bits()) == 0 {
}
if len(i2.Bits()) == 0 {
}
}
}
func BenchmarkBitLen(b *testing.B) {
i1 := big.NewInt(1)
i2 := big.NewInt(0)
for i := 0; i < b.N; i++ {
if i1.BitLen() == 0 {
}
if i2.BitLen() == 0 {
}
}
}
基准测试结果:
BenchmarkCompare-8 76975251 13.3 ns/op
BenchmarkBits-8 1000000000 0.656 ns/op
BenchmarkBitLen-8 1000000000 1.11 ns/op
获取位并将切片长度与 0
进行比较比将其与表示 0
的另一个 big.Int
进行比较快 20 倍,使用 Int.BitLen()
也 快 10 倍。
1。测试 1
可以做类似的事情来测试 big.Int
值是否等于 1
,但可能不如测试零快:0
是最特殊的值。它的内部表示是一个 nil
切片,任何其他值都需要一个非 nil
切片。另外:0
还有一个特殊的属性:它的绝对值就是它自己。
这个绝对值属性很重要,因为Int.Bits()
returns这个绝对值。因此,在 non-zero 值的情况下,仅检查位片是不够的,因为它不携带符号信息。
所以对1
的测试可以通过检查bits内容是否代表1
,并且符号为正来实现:
func isOne(i *big.Int) bool {
bits := i.Bits()
return len(bits) == 1 && bits[0] == 1 && i.Sign() > 0
}
让我们对此进行基准测试,并将数字与 one := big.NewInt(1)
进行比较:
func BenchmarkCompareOne(b *testing.B) {
one := big.NewInt(1)
i1 := big.NewInt(0)
i2 := big.NewInt(1)
i3 := big.NewInt(2)
for i := 0; i < b.N; i++ {
if i1.Cmp(one) == 0 {
}
if i2.Cmp(one) == 0 {
}
if i3.Cmp(one) == 0 {
}
}
}
func BenchmarkBitsOne(b *testing.B) {
i1 := big.NewInt(0)
i2 := big.NewInt(1)
i3 := big.NewInt(2)
for i := 0; i < b.N; i++ {
if isOne(i1) {
}
if isOne(i2) {
}
if isOne(i3) {
}
}
}
基准测试结果:
BenchmarkCompareOne-8 58631458 18.9 ns/op
BenchmarkBitsOne-8 715606629 1.76 ns/op
不错!我们测试 1 的方法再次 快 10 倍。
我正在使用 big.Int
s,需要测试 0。现在,我正在使用 zero = big.NewInt(0)
和 Cmp(zero)==0
,它们工作正常,但我想知道是否有专门针对 0 的更快方法吗(我需要这个程序非常快)?
big.Int
exposes Int.Bits()
访问表示的原始字节,它是一个切片并且共享相同的底层数组:不复制返回的切片。所以它很快。它暴露于 “支持实现缺少的 low-level Int 功能”。
完美,正是我们想要的。
0。测试 0
big.Int
的文档还指出 “Int 的零值表示值 0”。因此,在零值(表示 0
)中,切片将为空(切片的零值为 nil
,nil
切片的长度为 0
)。我们可以简单地检查一下:
if len(i1.Bits()) == 0 {
}
另请注意,有一个 Int.BitLen()
函数返回此值,它还声明 “0 的位长度为 0”。所以我们也可以用这个:
if i1.BitLen() == 0 {
}
让我们对这些解决方案进行基准测试:
func BenchmarkCompare(b *testing.B) {
zero := big.NewInt(0)
i1 := big.NewInt(1)
i2 := big.NewInt(0)
for i := 0; i < b.N; i++ {
if i1.Cmp(zero) == 0 {
}
if i2.Cmp(zero) == 0 {
}
}
}
func BenchmarkBits(b *testing.B) {
i1 := big.NewInt(1)
i2 := big.NewInt(0)
for i := 0; i < b.N; i++ {
if len(i1.Bits()) == 0 {
}
if len(i2.Bits()) == 0 {
}
}
}
func BenchmarkBitLen(b *testing.B) {
i1 := big.NewInt(1)
i2 := big.NewInt(0)
for i := 0; i < b.N; i++ {
if i1.BitLen() == 0 {
}
if i2.BitLen() == 0 {
}
}
}
基准测试结果:
BenchmarkCompare-8 76975251 13.3 ns/op
BenchmarkBits-8 1000000000 0.656 ns/op
BenchmarkBitLen-8 1000000000 1.11 ns/op
获取位并将切片长度与 0
进行比较比将其与表示 0
的另一个 big.Int
进行比较快 20 倍,使用 Int.BitLen()
也 快 10 倍。
1。测试 1
可以做类似的事情来测试 big.Int
值是否等于 1
,但可能不如测试零快:0
是最特殊的值。它的内部表示是一个 nil
切片,任何其他值都需要一个非 nil
切片。另外:0
还有一个特殊的属性:它的绝对值就是它自己。
这个绝对值属性很重要,因为Int.Bits()
returns这个绝对值。因此,在 non-zero 值的情况下,仅检查位片是不够的,因为它不携带符号信息。
所以对1
的测试可以通过检查bits内容是否代表1
,并且符号为正来实现:
func isOne(i *big.Int) bool {
bits := i.Bits()
return len(bits) == 1 && bits[0] == 1 && i.Sign() > 0
}
让我们对此进行基准测试,并将数字与 one := big.NewInt(1)
进行比较:
func BenchmarkCompareOne(b *testing.B) {
one := big.NewInt(1)
i1 := big.NewInt(0)
i2 := big.NewInt(1)
i3 := big.NewInt(2)
for i := 0; i < b.N; i++ {
if i1.Cmp(one) == 0 {
}
if i2.Cmp(one) == 0 {
}
if i3.Cmp(one) == 0 {
}
}
}
func BenchmarkBitsOne(b *testing.B) {
i1 := big.NewInt(0)
i2 := big.NewInt(1)
i3 := big.NewInt(2)
for i := 0; i < b.N; i++ {
if isOne(i1) {
}
if isOne(i2) {
}
if isOne(i3) {
}
}
}
基准测试结果:
BenchmarkCompareOne-8 58631458 18.9 ns/op
BenchmarkBitsOne-8 715606629 1.76 ns/op
不错!我们测试 1 的方法再次 快 10 倍。