Skip to content

Commit

Permalink
feat: frontend optimizations (#3781)
Browse files Browse the repository at this point in the history
a couple compilation-time optimizations. bring total time down by 5%
(`vyper -f bytecode`), and time in frontend code down by 20%
(`vyper -f annotated_ast`).

- cache `VyperNode.get_fields()`, it's a hotspot
- optimize `get_common_types(), this line is a hotspot;
  `rejected = [i for i in common_types if i not in common]`
  • Loading branch information
charles-cooper authored Feb 14, 2024
1 parent 4b4e188 commit 29205ba
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 6 deletions.
2 changes: 2 additions & 0 deletions vyper/ast/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import contextlib
import copy
import decimal
import functools
import operator
import sys
import warnings
Expand Down Expand Up @@ -341,6 +342,7 @@ def from_node(cls, node: "VyperNode", **kwargs) -> "VyperNode":
return cls(**ast_struct)

@classmethod
@functools.lru_cache(maxsize=None)
def get_fields(cls) -> set:
"""
Return a set of field names for this node.
Expand Down
14 changes: 8 additions & 6 deletions vyper/semantics/analysis/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,12 +500,14 @@ def get_common_types(*nodes: vy_ast.VyperNode, filter_fn: Callable = None) -> Li
for item in nodes[1:]:
new_types = _ExprAnalyser().get_possible_types_from_node(item)

common = [i for i in common_types if _is_type_in_list(i, new_types)]

rejected = [i for i in common_types if i not in common]
common += [i for i in new_types if _is_type_in_list(i, rejected)]

common_types = common
tmp = []
for c in common_types:
for t in new_types:
if t.compare_type(c) or c.compare_type(t):
tmp.append(c)
break

common_types = tmp

if filter_fn is not None:
common_types = [i for i in common_types if filter_fn(i)]
Expand Down

0 comments on commit 29205ba

Please sign in to comment.