core/vm, common/math: Add fast getByte for bigints, improve opByte

This commit is contained in:
Martin Holst Swende
2017-05-28 23:39:33 +02:00
parent 6171d01b11
commit 3285a0fda3
4 changed files with 169 additions and 8 deletions

View File

@ -21,6 +21,8 @@ import (
"encoding/hex"
"math/big"
"testing"
"github.com/ethereum/go-ethereum/common"
)
func TestHexOrDecimal256(t *testing.T) {
@ -133,8 +135,40 @@ func TestPaddedBigBytes(t *testing.T) {
}
}
func BenchmarkPaddedBigBytes(b *testing.B) {
func BenchmarkPaddedBigBytesLargePadding(b *testing.B) {
bigint := MustParseBig256("123456789123456789123456789123456789")
for i := 0; i < b.N; i++ {
PaddedBigBytes(bigint, 200)
}
}
func BenchmarkPaddedBigBytesSmallPadding(b *testing.B) {
bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC")
for i := 0; i < b.N; i++ {
PaddedBigBytes(bigint, 5)
}
}
func BenchmarkPaddedBigBytesSmallOnePadding(b *testing.B) {
bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC")
for i := 0; i < b.N; i++ {
PaddedBigBytes(bigint, 32)
}
}
func BenchmarkByteAtBrandNew(b *testing.B) {
bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC")
for i := 0; i < b.N; i++ {
BigEndian32ByteAt(bigint, 15)
}
}
func BenchmarkByteAt(b *testing.B) {
bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC")
for i := 0; i < b.N; i++ {
BigEndian32ByteAt(bigint, 15)
}
}
func BenchmarkByteAtOld(b *testing.B) {
bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC")
for i := 0; i < b.N; i++ {
PaddedBigBytes(bigint, 32)
}
@ -173,7 +207,64 @@ func TestU256(t *testing.T) {
}
}
}
func TestLittleEndianByteAt(t *testing.T) {
tests := []struct {
x string
y int
exp byte
}{
{"0", 0, 0x00},
{"1", 1, 0x00},
{"0", 1, 0x00},
//{"1", 0, 0x01},
{"0000000000000000000000000000000000000000000000000000000000102030", 0, 0x30},
{"0000000000000000000000000000000000000000000000000000000000102030", 1, 0x20},
{"ABCDEF0908070605040302010000000000000000000000000000000000000000", 31, 0xAB},
{"ABCDEF0908070605040302010000000000000000000000000000000000000000", 32, 0x00},
}
for _, test := range tests {
v := new(big.Int).SetBytes(common.Hex2Bytes(test.x))
actual := LittleEndianByteAt(v, test.y)
if actual != test.exp {
t.Fatalf("Expected [%v] %v:th byte to be %v, was %v.", test.x, test.y, test.exp, actual)
}
}
}
func TestBigEndianByteAt(t *testing.T) {
tests := []struct {
x string
y int
exp byte
}{
{"0", 0, 0x00},
{"1", 1, 0x00},
{"0", 1, 0x00},
{"1", 0, 0x00},
{"0000000000000000000000000000000000000000000000000000000000102030", 0, 0x00},
{"0000000000000000000000000000000000000000000000000000000000102030", 1, 0x00},
{"ABCDEF0908070605040302010000000000000000000000000000000000000000", 31, 0x00},
{"ABCDEF0908070605040302010000000000000000000000000000000000000000", 32, 0x00},
{"ABCDEF0908070605040302010000000000000000000000000000000000000000", 0, 0xAB},
{"ABCDEF0908070605040302010000000000000000000000000000000000000000", 1, 0xCD},
{"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", 0, 0x00},
{"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", 1, 0xCD},
{"0000000000000000000000000000000000000000000000000000000000102030", 31, 0x30},
{"0000000000000000000000000000000000000000000000000000000000102030", 30, 0x20},
{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 32, 0x0},
{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 0xFFFFFFFF, 0x0},
}
for _, test := range tests {
v := new(big.Int).SetBytes(common.Hex2Bytes(test.x))
actual := BigEndian32ByteAt(v, test.y)
if actual != test.exp {
t.Fatalf("Expected [%v] %v:th byte to be %v, was %v.", test.x, test.y, test.exp, actual)
}
}
}
func TestS256(t *testing.T) {
tests := []struct{ x, y *big.Int }{
{x: big.NewInt(0), y: big.NewInt(0)},