vm: optimize ROLL/ROT, refactor common code

Add `Roll` method to Stack that doesn't pop and push values and use it for
ROLL and ROT.

1.4M->1.5M 100K block import test before:
real    3m44,292s
user    5m43,494s
sys     0m34,741s

After:
real    3m40,449s
user    5m42,701s
sys     0m35,500s
This commit is contained in:
Roman Khimov 2019-12-16 19:53:21 +03:00
parent 2627628387
commit 587cfc7c66
4 changed files with 108 additions and 13 deletions

View file

@ -258,6 +258,46 @@ func TestSwapElemValues(t *testing.T) {
assert.Equal(t, int64(1), s.Pop().BigInt().Int64())
}
func TestRoll(t *testing.T) {
s := NewStack("test")
s.PushVal(1)
s.PushVal(2)
s.PushVal(3)
s.PushVal(4)
assert.NoError(t, s.Roll(2))
assert.Equal(t, int64(2), s.Pop().BigInt().Int64())
assert.Equal(t, int64(4), s.Pop().BigInt().Int64())
assert.Equal(t, int64(3), s.Pop().BigInt().Int64())
assert.Equal(t, int64(1), s.Pop().BigInt().Int64())
s.PushVal(1)
s.PushVal(2)
s.PushVal(3)
s.PushVal(4)
assert.NoError(t, s.Roll(3))
assert.Equal(t, int64(1), s.Pop().BigInt().Int64())
assert.Equal(t, int64(4), s.Pop().BigInt().Int64())
assert.Equal(t, int64(3), s.Pop().BigInt().Int64())
assert.Equal(t, int64(2), s.Pop().BigInt().Int64())
s.PushVal(1)
s.PushVal(2)
s.PushVal(3)
s.PushVal(4)
assert.Error(t, s.Roll(-1))
assert.Error(t, s.Roll(4))
assert.NoError(t, s.Roll(0))
assert.Equal(t, int64(4), s.Pop().BigInt().Int64())
assert.Equal(t, int64(3), s.Pop().BigInt().Int64())
assert.Equal(t, int64(2), s.Pop().BigInt().Int64())
assert.Equal(t, int64(1), s.Pop().BigInt().Int64())
}
func TestPopSigElements(t *testing.T) {
s := NewStack("test")