angr/claripy

`claripy.Extract` uses exponentation instead of a binary shift

Closed this issue · 1 comments

While profiling some code that used some rather large claripy.BVVs, I found that a lot of time was spent in claripy.Extract. I found that the main culprit is that the use of exponentiation to construct a bitmask instead of a shift. I used the below script to check that changing this exponentiation by a shift can result in a big increase in performance when the parameter values to claripy.Extract are large.

Current code

claripy/claripy/bv.py

Lines 290 to 291 in d8eeba6

def Extract(f, t, o):
return BVV((o.value >> t) & (2**(f+1) - 1), f-t+1)

Proposed change

def Extract(f, t, o):
    return BVV((o.value >> t) & ((1 << (f + 1)) - 1), f + 1 - t)

Test

main.py:

import claripy

def main():
    data = claripy.BVV(0, 25165824)
    for _ in range(100):
        claripy.Extract(25165823, 25133056, data)

if __name__ == "__main__":
    main()

With the current implementation, running this script takes 7.377 seconds using the command time python main.py. With the proposed improvement, running the same command takes only 0.480 seconds.

Awesome! Thank you. Do you want to send a PR?