-
Notifications
You must be signed in to change notification settings - Fork 1.8k
feat: optimize reject_recursive_repeats #3668
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Optimize web3._utils.decorators.reject_recursive_repeats |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,8 @@ | |
from typing import ( | ||
Any, | ||
Callable, | ||
Set, | ||
Tuple, | ||
TypeVar, | ||
cast, | ||
) | ||
|
@@ -20,21 +22,22 @@ def reject_recursive_repeats(to_wrap: Callable[..., Any]) -> Callable[..., Any]: | |
Prevent simple cycles by returning None when called recursively with same instance | ||
""" | ||
# types ignored b/c dynamically set attribute | ||
to_wrap.__already_called = {} # type: ignore | ||
already_called: Set[Tuple[int, ...]] = set() | ||
to_wrap.__already_called = already_called # type: ignore | ||
|
||
add_call = already_called.add | ||
remove_call = already_called.remove | ||
|
||
@functools.wraps(to_wrap) | ||
def wrapped(*args: Any) -> Any: | ||
arg_instances = tuple(map(id, args)) | ||
thread_id = threading.get_ident() | ||
thread_local_args = (thread_id,) + arg_instances | ||
if thread_local_args in to_wrap.__already_called: # type: ignore | ||
thread_local_args = (threading.get_ident(), *map(id, args)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -2 var assignments, -2 var reads, -2 tuple creations per call |
||
if thread_local_args in already_called: | ||
raise Web3ValueError(f"Recursively called {to_wrap} with {args!r}") | ||
to_wrap.__already_called[thread_local_args] = True # type: ignore | ||
add_call(thread_local_args) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -1 attr lookup, -1 setitem per call |
||
try: | ||
wrapped_val = to_wrap(*args) | ||
return to_wrap(*args) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -1 set var, -1 var lookup per call |
||
finally: | ||
del to_wrap.__already_called[thread_local_args] # type: ignore | ||
return wrapped_val | ||
remove_call(thread_local_args) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -1 attr lookup per call |
||
|
||
return wrapped | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 less attr lookup per access