vm: optimize SWAP instruction, refactor common code
Add `Swap` method to the Stack and use it for both SWAP and XSWAP. Avoid element popping and pushing (and associated accounting costs). 1.4M->1.5M 100K block import test before: real 3m51,885s user 5m54,744s sys 0m38,444s After: real 3m44,292s user 5m43,494s sys 0m34,741s
This commit is contained in:
parent
b78896f2e1
commit
2627628387
4 changed files with 115 additions and 30 deletions
|
@ -2,6 +2,7 @@ package vm
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
|
@ -371,6 +372,23 @@ func (s *Stack) IterBack(f func(*Element)) {
|
|||
}
|
||||
}
|
||||
|
||||
// Swap swaps two elements on the stack without popping and pushing them.
|
||||
func (s *Stack) Swap(n1, n2 int) error {
|
||||
if n1 < 0 || n2 < 0 {
|
||||
return errors.New("negative index")
|
||||
}
|
||||
if n1 >= s.len || n2 >= s.len {
|
||||
return errors.New("too big index")
|
||||
}
|
||||
if n1 == n2 {
|
||||
return nil
|
||||
}
|
||||
a := s.Peek(n1)
|
||||
b := s.Peek(n2)
|
||||
a.value, b.value = b.value, a.value
|
||||
return nil
|
||||
}
|
||||
|
||||
// popSigElements pops keys or signatures from the stack as needed for
|
||||
// CHECKMULTISIG.
|
||||
func (s *Stack) popSigElements() ([][]byte, error) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue