2021-12-04 16:42:11 +00:00

800 lines
26 KiB
Go

// uint256: Fixed size 256-bit math library
// Copyright 2020 uint256 Authors
// SPDX-License-Identifier: BSD-3-Clause
package uint256
import (
"math/big"
"math/rand"
"testing"
)
const numSamples = 1024
var (
int32Samples [numSamples]Int
int32SamplesLt [numSamples]Int
int64Samples [numSamples]Int
int64SamplesLt [numSamples]Int
int128Samples [numSamples]Int
int128SamplesLt [numSamples]Int
int192Samples [numSamples]Int
int192SamplesLt [numSamples]Int
int256Samples [numSamples]Int
int256SamplesLt [numSamples]Int // int256SamplesLt[i] <= int256Samples[i]
big32Samples [numSamples]big.Int
big32SamplesLt [numSamples]big.Int
big64Samples [numSamples]big.Int
big64SamplesLt [numSamples]big.Int
big128Samples [numSamples]big.Int
big128SamplesLt [numSamples]big.Int
big192Samples [numSamples]big.Int
big192SamplesLt [numSamples]big.Int
big256Samples [numSamples]big.Int
big256SamplesLt [numSamples]big.Int // big256SamplesLt[i] <= big256Samples[i]
_ = initSamples()
)
func initSamples() bool {
rnd := rand.New(rand.NewSource(0))
// newRandInt creates new Int with so many highly likely non-zero random words.
newRandInt := func(numWords int) Int {
var z Int
for i := 0; i < numWords; i++ {
z[i] = rnd.Uint64()
}
return z
}
for i := 0; i < numSamples; i++ {
x32g := rnd.Uint32()
x32l := rnd.Uint32()
if x32g < x32l {
x32g, x32l = x32l, x32g
}
int32Samples[i].SetUint64(uint64(x32g))
big32Samples[i] = *int32Samples[i].ToBig()
int32SamplesLt[i].SetUint64(uint64(x32l))
big32SamplesLt[i] = *int32SamplesLt[i].ToBig()
l := newRandInt(1)
g := newRandInt(1)
if g.Lt(&l) {
g,l = l,g
}
if g[0] == 0 {
g[0]++
}
int64Samples[i] = g
big64Samples[i] = *int64Samples[i].ToBig()
int64SamplesLt[i] = l
big64SamplesLt[i] = *int64SamplesLt[i].ToBig()
l = newRandInt(2)
g = newRandInt(2)
if g.Lt(&l) {
g,l = l,g
}
if g[1] == 0 {
g[1]++
}
int128Samples[i] = g
big128Samples[i] = *int128Samples[i].ToBig()
int128SamplesLt[i] = l
big128SamplesLt[i] = *int128SamplesLt[i].ToBig()
l = newRandInt(3)
g = newRandInt(3)
if g.Lt(&l) {
g,l = l,g
}
if g[2] == 0 {
g[2]++
}
int192Samples[i] = g
big192Samples[i] = *int192Samples[i].ToBig()
int192SamplesLt[i] = l
big192SamplesLt[i] = *int192SamplesLt[i].ToBig()
l = newRandInt(4)
g = newRandInt(4)
if g.Lt(&l) {
g,l = l,g
}
if g[3] == 0 {
g[3]++
}
int256Samples[i] = g
big256Samples[i] = *int256Samples[i].ToBig()
int256SamplesLt[i] = l
big256SamplesLt[i] = *int256SamplesLt[i].ToBig()
}
return true
}
func benchmark_Add_Bit(bench *testing.B) {
b1 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
b2 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdefaaaaaa9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
f, _ := FromBig(b1)
f2, _ := FromBig(b2)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
f.Add(f, f2)
}
}
func benchmark_Add_Big(bench *testing.B) {
b := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
b2 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdefaaaaaa9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
b.Add(b, b2)
}
}
func Benchmark_Add(bench *testing.B) {
bench.Run("single/big", benchmark_Add_Big)
bench.Run("single/uint256", benchmark_Add_Bit)
}
func benchmark_SubOverflow_Bit(bench *testing.B) {
b1 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
b2 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdefaaaaaa9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
f, _ := FromBig(b1)
f2, _ := FromBig(b2)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
f.SubOverflow(f, f2)
}
}
func benchmark_Sub_Bit(bench *testing.B) {
b1 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
b2 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdefaaaaaa9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
f, _ := FromBig(b1)
f2, _ := FromBig(b2)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
f.Sub(f, f2)
}
}
func benchmark_Sub_Big(bench *testing.B) {
b1 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
b2 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdefaaaaaa9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
b1.Sub(b1, b2)
}
}
func Benchmark_Sub(bench *testing.B) {
bench.Run("single/big", benchmark_Sub_Big)
bench.Run("single/uint256", benchmark_Sub_Bit)
bench.Run("single/uint256_of", benchmark_SubOverflow_Bit)
}
func BenchmarkMul(bench *testing.B) {
benchmarkUint256 := func(bench *testing.B) {
a := big.NewInt(0).SetBytes(hex2Bytes("f123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
b := big.NewInt(0).SetBytes(hex2Bytes("f123456789abcdefaaaaaa9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
fa, _ := FromBig(a)
fb, _ := FromBig(b)
result := new(Int)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
result.Mul(fa, fb)
}
}
benchmarkBig := func(bench *testing.B) {
a := new(big.Int).SetBytes(hex2Bytes("f123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
b := new(big.Int).SetBytes(hex2Bytes("f123456789abcdefaaaaaa9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
result := new(big.Int)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
U256(result.Mul(a, b))
}
}
bench.Run("single/uint256", benchmarkUint256)
bench.Run("single/big", benchmarkBig)
}
func BenchmarkMulOverflow(bench *testing.B) {
benchmarkUint256 := func(bench *testing.B) {
a := big.NewInt(0).SetBytes(hex2Bytes("f123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
b := big.NewInt(0).SetBytes(hex2Bytes("f123456789abcdefaaaaaa9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
fa, _ := FromBig(a)
fb, _ := FromBig(b)
result := new(Int)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
result.MulOverflow(fa, fb)
}
}
benchmarkBig := func(bench *testing.B) {
a := new(big.Int).SetBytes(hex2Bytes("f123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
b := new(big.Int).SetBytes(hex2Bytes("f123456789abcdefaaaaaa9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
result := new(big.Int)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
U256(result.Mul(a, b))
}
}
bench.Run("single/uint256", benchmarkUint256)
bench.Run("single/big", benchmarkBig)
}
func BenchmarkSquare(bench *testing.B) {
benchmarkUint256 := func(bench *testing.B) {
a := new(Int).SetBytes(hex2Bytes("f123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
result := new(Int)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
result.Set(a).squared()
}
}
benchmarkBig := func(bench *testing.B) {
a := new(big.Int).SetBytes(hex2Bytes("f123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
result := new(big.Int)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
U256(result.Mul(a, a))
}
}
bench.Run("single/uint256", benchmarkUint256)
bench.Run("single/big", benchmarkBig)
}
func benchmark_And_Big(bench *testing.B) {
b1 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
b2 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdefaaaaaa9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
b1.And(b1, b2)
}
}
func benchmark_And_Bit(bench *testing.B) {
b1 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
b2 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdefaaaaaa9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
f, _ := FromBig(b1)
f2, _ := FromBig(b2)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
f.And(f, f2)
}
}
func Benchmark_And(bench *testing.B) {
bench.Run("single/big", benchmark_And_Big)
bench.Run("single/uint256", benchmark_And_Bit)
}
func benchmark_Or_Big(bench *testing.B) {
b1 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
b2 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdefaaaaaa9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
b1.Or(b1, b2)
}
}
func benchmark_Or_Bit(bench *testing.B) {
b1 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
b2 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdefaaaaaa9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
f, _ := FromBig(b1)
f2, _ := FromBig(b2)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
f.Or(f, f2)
}
}
func Benchmark_Or(bench *testing.B) {
bench.Run("single/big", benchmark_Or_Big)
bench.Run("single/uint256", benchmark_Or_Bit)
}
func benchmark_Xor_Big(bench *testing.B) {
b1 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
b2 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdefaaaaaa9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
b1.Xor(b1, b2)
}
}
func benchmark_Xor_Bit(bench *testing.B) {
b1 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
b2 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdefaaaaaa9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
f, _ := FromBig(b1)
f2, _ := FromBig(b2)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
f.Xor(f, f2)
}
}
func Benchmark_Xor(bench *testing.B) {
bench.Run("single/big", benchmark_Xor_Big)
bench.Run("single/uint256", benchmark_Xor_Bit)
}
func benchmark_Cmp_Big(bench *testing.B) {
b1 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
b2 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdefaaaaaa9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
b1.Cmp(b2)
b2.Cmp(b1)
}
}
func benchmark_Cmp_Bit(bench *testing.B) {
b1 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdeffedcba9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
b2 := big.NewInt(0).SetBytes(hex2Bytes("0123456789abcdefaaaaaa9876543210f2f3f4f5f6f7f8f9fff3f4f5f6f7f8f9"))
f, _ := FromBig(b1)
f2, _ := FromBig(b2)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
f.Cmp(f2)
f2.Cmp(f)
}
}
func Benchmark_Cmp(bench *testing.B) {
bench.Run("single/big", benchmark_Cmp_Big)
bench.Run("single/uint256", benchmark_Cmp_Bit)
}
func BenchmarkLt(b *testing.B) {
benchmarkUint256 := func(b *testing.B, samples *[numSamples]Int) (flag bool) {
var x Int
for j := 0; j < b.N; j += numSamples {
for i := 0; i < numSamples; i++ {
y := samples[i]
flag = x.Lt(&y)
x = y
}
}
return
}
benchmarkBig := func(b *testing.B, samples *[numSamples]big.Int) (flag bool) {
var x big.Int
for j := 0; j < b.N; j += numSamples {
for i := 0; i < numSamples; i++ {
y := samples[i]
flag = x.Cmp(&y) < 0
x = y
}
}
return
}
b.Run("large/uint256", func(b *testing.B) { benchmarkUint256(b, &int256Samples) })
b.Run("large/big", func(b *testing.B) { benchmarkBig(b, &big256Samples) })
b.Run("small/uint256", func(b *testing.B) { benchmarkUint256(b, &int64Samples) })
b.Run("small/big", func(b *testing.B) { benchmarkBig(b, &big64Samples) })
}
func benchmark_Lsh_Big(n uint, bench *testing.B) {
original := big.NewInt(0).SetBytes(hex2Bytes("FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"))
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
b1 := big.NewInt(0)
b1.Lsh(original, n)
}
}
func benchmark_Lsh_Big_N_EQ_0(bench *testing.B) {
benchmark_Lsh_Big(0, bench)
}
func benchmark_Lsh_Big_N_GT_192(bench *testing.B) {
benchmark_Lsh_Big(193, bench)
}
func benchmark_Lsh_Big_N_GT_128(bench *testing.B) {
benchmark_Lsh_Big(129, bench)
}
func benchmark_Lsh_Big_N_GT_64(bench *testing.B) {
benchmark_Lsh_Big(65, bench)
}
func benchmark_Lsh_Big_N_GT_0(bench *testing.B) {
benchmark_Lsh_Big(1, bench)
}
func benchmark_Lsh_Bit(n uint, bench *testing.B) {
original := big.NewInt(0).SetBytes(hex2Bytes("FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"))
f2, _ := FromBig(original)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
f1 := new(Int)
f1.Lsh(f2, n)
}
}
func benchmark_Lsh_Bit_N_EQ_0(bench *testing.B) {
benchmark_Lsh_Bit(0, bench)
}
func benchmark_Lsh_Bit_N_GT_192(bench *testing.B) {
benchmark_Lsh_Bit(193, bench)
}
func benchmark_Lsh_Bit_N_GT_128(bench *testing.B) {
benchmark_Lsh_Bit(129, bench)
}
func benchmark_Lsh_Bit_N_GT_64(bench *testing.B) {
benchmark_Lsh_Bit(65, bench)
}
func benchmark_Lsh_Bit_N_GT_0(bench *testing.B) {
benchmark_Lsh_Bit(1, bench)
}
func Benchmark_Lsh(bench *testing.B) {
bench.Run("n_eq_0/big", benchmark_Lsh_Big_N_EQ_0)
bench.Run("n_gt_192/big", benchmark_Lsh_Big_N_GT_192)
bench.Run("n_gt_128/big", benchmark_Lsh_Big_N_GT_128)
bench.Run("n_gt_64/big", benchmark_Lsh_Big_N_GT_64)
bench.Run("n_gt_0/big", benchmark_Lsh_Big_N_GT_0)
bench.Run("n_eq_0/uint256", benchmark_Lsh_Bit_N_EQ_0)
bench.Run("n_gt_192/uint256", benchmark_Lsh_Bit_N_GT_192)
bench.Run("n_gt_128/uint256", benchmark_Lsh_Bit_N_GT_128)
bench.Run("n_gt_64/uint256", benchmark_Lsh_Bit_N_GT_64)
bench.Run("n_gt_0/uint256", benchmark_Lsh_Bit_N_GT_0)
}
func benchmark_Rsh_Big(n uint, bench *testing.B) {
original := big.NewInt(0).SetBytes(hex2Bytes("FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"))
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
b1 := big.NewInt(0)
b1.Rsh(original, n)
}
}
func benchmark_Rsh_Big_N_EQ_0(bench *testing.B) {
benchmark_Rsh_Big(0, bench)
}
func benchmark_Rsh_Big_N_GT_192(bench *testing.B) {
benchmark_Rsh_Big(193, bench)
}
func benchmark_Rsh_Big_N_GT_128(bench *testing.B) {
benchmark_Rsh_Big(129, bench)
}
func benchmark_Rsh_Big_N_GT_64(bench *testing.B) {
benchmark_Rsh_Big(65, bench)
}
func benchmark_Rsh_Big_N_GT_0(bench *testing.B) {
benchmark_Rsh_Big(1, bench)
}
func benchmark_Rsh_Bit(n uint, bench *testing.B) {
original := big.NewInt(0).SetBytes(hex2Bytes("FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"))
f2, _ := FromBig(original)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
f1 := new(Int)
f1.Rsh(f2, n)
}
}
func benchmark_Rsh_Bit_N_EQ_0(bench *testing.B) {
benchmark_Rsh_Bit(0, bench)
}
func benchmark_Rsh_Bit_N_GT_192(bench *testing.B) {
benchmark_Rsh_Bit(193, bench)
}
func benchmark_Rsh_Bit_N_GT_128(bench *testing.B) {
benchmark_Rsh_Bit(129, bench)
}
func benchmark_Rsh_Bit_N_GT_64(bench *testing.B) {
benchmark_Rsh_Bit(65, bench)
}
func benchmark_Rsh_Bit_N_GT_0(bench *testing.B) {
benchmark_Rsh_Bit(1, bench)
}
func Benchmark_Rsh(bench *testing.B) {
bench.Run("n_eq_0/big", benchmark_Rsh_Big_N_EQ_0)
bench.Run("n_gt_192/big", benchmark_Rsh_Big_N_GT_192)
bench.Run("n_gt_128/big", benchmark_Rsh_Big_N_GT_128)
bench.Run("n_gt_64/big", benchmark_Rsh_Big_N_GT_64)
bench.Run("n_gt_0/big", benchmark_Rsh_Big_N_GT_0)
bench.Run("n_eq_0/uint256", benchmark_Rsh_Bit_N_EQ_0)
bench.Run("n_gt_192/uint256", benchmark_Rsh_Bit_N_GT_192)
bench.Run("n_gt_128/uint256", benchmark_Rsh_Bit_N_GT_128)
bench.Run("n_gt_64/uint256", benchmark_Rsh_Bit_N_GT_64)
bench.Run("n_gt_0/uint256", benchmark_Rsh_Bit_N_GT_0)
}
func benchmark_Exp_Big(bench *testing.B) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
orig := big.NewInt(0).SetBytes(hex2Bytes(x))
base := big.NewInt(0).SetBytes(hex2Bytes(x))
exp := big.NewInt(0).SetBytes(hex2Bytes(y))
result := new(big.Int)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
Exp(result, base, exp)
base.Set(orig)
}
}
func benchmark_Exp_Bit(bench *testing.B) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
base := big.NewInt(0).SetBytes(hex2Bytes(x))
exp := big.NewInt(0).SetBytes(hex2Bytes(y))
f_base, _ := FromBig(base)
f_orig, _ := FromBig(base)
f_exp, _ := FromBig(exp)
f_res := Int{}
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
f_res.Exp(f_base, f_exp)
f_base.Set(f_orig)
}
}
func benchmark_ExpSmall_Big(bench *testing.B) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "8abcdef"
orig := big.NewInt(0).SetBytes(hex2Bytes(x))
base := big.NewInt(0).SetBytes(hex2Bytes(x))
exp := big.NewInt(0).SetBytes(hex2Bytes(y))
result := new(big.Int)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
Exp(result, base, exp)
base.Set(orig)
}
}
func benchmark_ExpSmall_Bit(bench *testing.B) {
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
y := "8abcdef"
base := big.NewInt(0).SetBytes(hex2Bytes(x))
exp := big.NewInt(0).SetBytes(hex2Bytes(y))
f_base, _ := FromBig(base)
f_orig, _ := FromBig(base)
f_exp, _ := FromBig(exp)
f_res := Int{}
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
f_res.Exp(f_base, f_exp)
f_base.Set(f_orig)
}
}
func Benchmark_Exp(bench *testing.B) {
bench.Run("large/big", benchmark_Exp_Big)
bench.Run("large/uint256", benchmark_Exp_Bit)
bench.Run("small/big", benchmark_ExpSmall_Big)
bench.Run("small/uint256", benchmark_ExpSmall_Bit)
}
func BenchmarkDiv(b *testing.B) {
benchmarkDivUint256 := func(b *testing.B, xSamples, modSamples *[numSamples]Int) {
var sink Int
for j := 0; j < b.N; j += numSamples {
for i := 0; i < numSamples; i++ {
sink.Div(&xSamples[i], &modSamples[i])
}
}
}
benchmarkDivBig := func(b *testing.B, xSamples, modSamples *[numSamples]big.Int) {
var sink big.Int
for j := 0; j < b.N; j += numSamples {
for i := 0; i < numSamples; i++ {
sink.Div(&xSamples[i], &modSamples[i])
}
}
}
b.Run("small/uint256", func(b *testing.B) { benchmarkDivUint256(b, &int32Samples, &int32SamplesLt) })
b.Run("small/big", func(b *testing.B) { benchmarkDivBig(b, &big32Samples, &big32SamplesLt) })
b.Run("mod64/uint256", func(b *testing.B) { benchmarkDivUint256(b, &int256Samples, &int64Samples) })
b.Run("mod64/big", func(b *testing.B) { benchmarkDivBig(b, &big256Samples, &big64Samples) })
b.Run("mod128/uint256", func(b *testing.B) { benchmarkDivUint256(b, &int256Samples, &int128Samples) })
b.Run("mod128/big", func(b *testing.B) { benchmarkDivBig(b, &big256Samples, &big128Samples) })
b.Run("mod192/uint256", func(b *testing.B) { benchmarkDivUint256(b, &int256Samples, &int192Samples) })
b.Run("mod192/big", func(b *testing.B) { benchmarkDivBig(b, &big256Samples, &big192Samples) })
b.Run("mod256/uint256", func(b *testing.B) { benchmarkDivUint256(b, &int256Samples, &int256SamplesLt) })
b.Run("mod256/big", func(b *testing.B) { benchmarkDivBig(b, &big256Samples, &big256SamplesLt) })
}
func BenchmarkMod(b *testing.B) {
benchmarkModUint256 := func(b *testing.B, xSamples, modSamples *[numSamples]Int) {
var sink Int
for j := 0; j < b.N; j += numSamples {
for i := 0; i < numSamples; i++ {
sink.Mod(&xSamples[i], &modSamples[i])
}
}
}
benchmarkModBig := func(b *testing.B, xSamples, modSamples *[numSamples]big.Int) {
var sink big.Int
for j := 0; j < b.N; j += numSamples {
for i := 0; i < numSamples; i++ {
sink.Mod(&xSamples[i], &modSamples[i])
}
}
}
b.Run("small/uint256", func(b *testing.B) { benchmarkModUint256(b, &int32Samples, &int32SamplesLt) })
b.Run("small/big", func(b *testing.B) { benchmarkModBig(b, &big32Samples, &big32SamplesLt) })
b.Run("mod64/uint256", func(b *testing.B) { benchmarkModUint256(b, &int256Samples, &int64Samples) })
b.Run("mod64/big", func(b *testing.B) { benchmarkModBig(b, &big256Samples, &big64Samples) })
b.Run("mod128/uint256", func(b *testing.B) { benchmarkModUint256(b, &int256Samples, &int128Samples) })
b.Run("mod128/big", func(b *testing.B) { benchmarkModBig(b, &big256Samples, &big128Samples) })
b.Run("mod192/uint256", func(b *testing.B) { benchmarkModUint256(b, &int256Samples, &int192Samples) })
b.Run("mod192/big", func(b *testing.B) { benchmarkModBig(b, &big256Samples, &big192Samples) })
b.Run("mod256/uint256", func(b *testing.B) { benchmarkModUint256(b, &int256Samples, &int256SamplesLt) })
b.Run("mod256/big", func(b *testing.B) { benchmarkModBig(b, &big256Samples, &big256SamplesLt) })
}
func BenchmarkAddMod(b *testing.B) {
benchmarkAddModUint256 := func(b *testing.B, factorsSamples, modSamples *[numSamples]Int) {
iter := (b.N + numSamples - 1) / numSamples
for j := 0; j < numSamples; j++ {
var x Int
y := factorsSamples[j]
for i := 0; i < iter; i++ {
x.AddMod(&x, &y, &modSamples[j])
}
}
}
benchmarkAddModBig := func(b *testing.B, factorsSamples, modSamples *[numSamples]big.Int) {
iter := (b.N + numSamples - 1) / numSamples
for j := 0; j < numSamples; j++ {
var x big.Int
y := factorsSamples[j]
for i := 0; i < iter; i++ {
x.Add(&x, &y)
x.Mod(&x, &modSamples[j])
}
}
}
b.Run("small/uint256", func(b *testing.B) { benchmarkAddModUint256 (b, &int32SamplesLt, &int32Samples) })
b.Run("small/big", func(b *testing.B) { benchmarkAddModBig (b, &big32SamplesLt, &big32Samples) })
b.Run("mod64/uint256", func(b *testing.B) { benchmarkAddModUint256 (b, &int64SamplesLt, &int64Samples) })
b.Run("mod64/big", func(b *testing.B) { benchmarkAddModBig (b, &big64SamplesLt, &big64Samples) })
b.Run("mod128/uint256", func(b *testing.B) { benchmarkAddModUint256 (b, &int128SamplesLt, &int128Samples) })
b.Run("mod128/big", func(b *testing.B) { benchmarkAddModBig (b, &big128SamplesLt, &big128Samples) })
b.Run("mod192/uint256", func(b *testing.B) { benchmarkAddModUint256 (b, &int192SamplesLt, &int192Samples) })
b.Run("mod192/big", func(b *testing.B) { benchmarkAddModBig (b, &big192SamplesLt, &big192Samples) })
b.Run("mod256/uint256", func(b *testing.B) { benchmarkAddModUint256 (b, &int256SamplesLt, &int256Samples) })
b.Run("mod256/big", func(b *testing.B) { benchmarkAddModBig (b, &big256SamplesLt, &big256Samples) })
}
func BenchmarkMulMod(b *testing.B) {
benchmarkMulModUint256 := func(b *testing.B, factorsSamples, modSamples *[numSamples]Int) {
iter := (b.N + numSamples - 1) / numSamples
for j := 0; j < numSamples; j++ {
x := factorsSamples[j]
for i := 0; i < iter; i++ {
x.MulMod(&x, &factorsSamples[j], &modSamples[j])
}
}
}
benchmarkMulModBig := func(b *testing.B, factorsSamples, modSamples *[numSamples]big.Int) {
iter := (b.N + numSamples - 1) / numSamples
for j := 0; j < numSamples; j++ {
x := factorsSamples[j]
for i := 0; i < iter; i++ {
x.Mul(&x, &factorsSamples[j])
x.Mod(&x, &modSamples[j])
}
}
}
b.Run("small/uint256", func(b *testing.B) { benchmarkMulModUint256 (b, &int32SamplesLt, &int32Samples) })
b.Run("small/big", func(b *testing.B) { benchmarkMulModBig (b, &big32SamplesLt, &big32Samples) })
b.Run("mod64/uint256", func(b *testing.B) { benchmarkMulModUint256 (b, &int64SamplesLt, &int64Samples) })
b.Run("mod64/big", func(b *testing.B) { benchmarkMulModBig (b, &big64SamplesLt, &big64Samples) })
b.Run("mod128/uint256", func(b *testing.B) { benchmarkMulModUint256 (b, &int128SamplesLt, &int128Samples) })
b.Run("mod128/big", func(b *testing.B) { benchmarkMulModBig (b, &big128SamplesLt, &big128Samples) })
b.Run("mod192/uint256", func(b *testing.B) { benchmarkMulModUint256 (b, &int192SamplesLt, &int192Samples) })
b.Run("mod192/big", func(b *testing.B) { benchmarkMulModBig (b, &big192SamplesLt, &big192Samples) })
b.Run("mod256/uint256", func(b *testing.B) { benchmarkMulModUint256 (b, &int256SamplesLt, &int256Samples) })
b.Run("mod256/big", func(b *testing.B) { benchmarkMulModBig (b, &big256SamplesLt, &big256Samples) })
}
func benchmark_SdivLarge_Big(bench *testing.B) {
a := new(big.Int).SetBytes(hex2Bytes("800fffffffffffffffffffffffffd1e870eec79504c60144cc7f5fc2bad1e611"))
b := new(big.Int).SetBytes(hex2Bytes("ff3f9014f20db29ae04af2c2d265de17"))
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
U256(SDiv(new(big.Int), a, b))
}
}
func benchmark_SdivLarge_Bit(bench *testing.B) {
a := big.NewInt(0).SetBytes(hex2Bytes("800fffffffffffffffffffffffffd1e870eec79504c60144cc7f5fc2bad1e611"))
b := big.NewInt(0).SetBytes(hex2Bytes("ff3f9014f20db29ae04af2c2d265de17"))
fa, _ := FromBig(a)
fb, _ := FromBig(b)
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
f := new(Int)
f.SDiv(fa, fb)
}
}
func Benchmark_SDiv(bench *testing.B) {
bench.Run("large/big", benchmark_SdivLarge_Big)
bench.Run("large/uint256", benchmark_SdivLarge_Bit)
}
func Benchmark_EncodeHex(b *testing.B) {
hexEncodeU256 := func(b *testing.B, samples *[numSamples]Int) {
b.ReportAllocs()
for j := 0; j < b.N; j += numSamples {
for i := 0; i < numSamples; i++ {
samples[i].Hex()
}
}
}
hexEncodeBig := func(b *testing.B, samples *[numSamples]big.Int) {
b.ReportAllocs()
for j := 0; j < b.N; j += numSamples {
for i := 0; i < numSamples; i++ {
// We're being nice to big.Int here, because this method
// does not add the 0x-prefix -- so an extra alloc is needed to get
// the same result. We still win the benchmark though...
samples[i].Text(16)
}
}
}
b.Run("large/uint256", func(b *testing.B) { hexEncodeU256(b, &int256Samples) })
b.Run("large/big", func(b *testing.B) { hexEncodeBig(b, &big256Samples) })
}
func Benchmark_DecodeHex(b *testing.B) {
var hexStrings []string
for _, z := range &int256Samples {
hexStrings = append(hexStrings, (&z).Hex())
}
hexDecodeU256 := func(b *testing.B, samples *[numSamples]Int) {
b.ReportAllocs()
//var sink Int
for j := 0; j < b.N; j += numSamples {
for i := 0; i < numSamples; i++ {
_, _ = FromHex(hexStrings[i])
}
}
}
hexDecodeBig := func(b *testing.B, samples *[numSamples]big.Int) {
b.ReportAllocs()
//var sink big.Int
for j := 0; j < b.N; j += numSamples {
for i := 0; i < numSamples; i++ {
big.NewInt(0).SetString(hexStrings[i], 16)
}
}
}
b.Run("large/uint256", func(b *testing.B) { hexDecodeU256(b, &int256Samples) })
b.Run("large/big", func(b *testing.B) { hexDecodeBig(b, &big256Samples) })
}