py-evm icon indicating copy to clipboard operation
py-evm copied to clipboard

[WIP] Refactor Stack to eliminate mix types

Open Bhargavasomu opened this issue 6 years ago • 4 comments

What was wrong?

As part of Issue #1656

How was it fixed?

The Stack now stores only objects of type int. It previously also used to store bytes. Now the bytes are converted to int before storing on the stack, and any the Stack issues out the popped elements in the form of int. It is expected to convert the integers to bytes at the call site, wherever necessary.

Cute Animal Picture

put a cute animal picture link inside the parentheses

Bhargavasomu avatar Dec 21 '18 07:12 Bhargavasomu

@cburgdorf We can see the Stack performance comparison for the old version and the new version under py36-stack-benchmark. But I feel that just comparing the Stack Times is not a good benchmark, because we can see that performance decrease while pushing and increases while popping, when compared to the old one. So we might not still get a full idea of the performance change.

A better benchmark would be comparing the times taken to run a computation (like a benchmark bytecode) between the old and the new version. This way we would get an overall performance feel caused by the changes. Hence, where can I find a bunch of sample bytecodes to run the benchmarks against them? Are they somewhere in the fixtures directory?

Bhargavasomu avatar Dec 27 '18 11:12 Bhargavasomu

Some Points to Note

  • There are lots of places in the code which has to be deleted, but were kept for running the benchmarks. Will delete them once confirmed with the procedure.
  • I just implemented pop and pop_n functions instead of pop1, pop2, pop3 because there are places in the codebase which requires the popping of 5 elements, and I felt that this approach was not so feasible.
  • And I have directly used the following method as it was faster than the other methods suggested by @pipermerriam. I have tested these on a sample stack. Will add this benchmark too if needed.
def pop3(self):
    try:
        return (self.values.pop(), self.values.pop(), self.values.pop())
    except IndexError:
        raise InsufficientStack("...")

Bhargavasomu avatar Dec 27 '18 11:12 Bhargavasomu

There are lots of places in the code which has to be deleted, but were kept for running the benchmarks. Will delete them once confirmed with the procedure.

To do this we should first write the benchmark code against master and get that merged. Then you can switch back and forth between your branch and master to compare benchmarks.

pipermerriam avatar Jan 04 '19 22:01 pipermerriam

I just implemented pop and pop_n functions instead of pop1, pop2, pop3 because there are places in the codebase which requires the popping of 5 elements, and I felt that this approach was not so feasible.

I'm still leaning pretty heavily towards just having pop1, pop2, for every number of elements that we need to pop. It may not be very DRY but it will be highly performant and shouldn't result in much of any code maintenance since it's unlikely to change. Each of these APIs would need to be replicated on the Computation object as well.

pipermerriam avatar Jan 04 '19 22:01 pipermerriam