Skip to content

Commit

Permalink
doccursor: cache calls to certain internal methods
Browse files Browse the repository at this point in the history
As I kept an eye on performance throughout this series, I thought
caching could save a few calls to some reasonably complex functions. As
I was doing it though, it became obvious it wouldn't improve much, but
it has its advantages and it seems worth a few lines of code and all 5
minutes it took to implement.

Right now, this only really saves any time on the type fixup method,
which is called 2-3 times on any given cursor (not counting recursion).
And that should not make much of a difference, naturally.

On the upside:
- Once we pass the cursors to docstring and start calling them in situ,
  we will likely be calling on these properties a lot more often.
- Once cursors get passed to user land through extensions, caching can
  save an arbitrary amount of calls.
- Should always be useful no matter how the cursor object evolves.
- It's a simple concept to maintain.

On the downside:
- It doesn't really improve performance on our test suite in any
  meaningful way.
- There are probably other clean-ups more relevant to performance,
  though not as easy to achieve as this one :)
  • Loading branch information
BrunoMSantos committed Nov 16, 2023
1 parent 34282b3 commit fa2f246
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions src/hawkmoth/doccursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,17 @@ def __init__(self, domain=None, cursor=None, comments=None):
else:
self._comment = None

self._cache_store = {}

def __hash__(self):
return self._cc.hash

def _cache(self, func, *args):
name = func.__name__
if name not in self._cache_store:
self._cache_store[name] = func(*args)
return self._cache_store[name]

@property
def meta(self):
return {
Expand Down Expand Up @@ -67,27 +75,27 @@ def name(self):
@property
def decl_name(self):
if self._cc.kind in [CursorKind.VAR_DECL, CursorKind.FIELD_DECL]:
return self._var_type_fixup(self)[1]
return self._cache(self._var_type_fixup, self)[1]
if self._cc.kind in [CursorKind.STRUCT_DECL,
CursorKind.UNION_DECL,
CursorKind.ENUM_DECL,
CursorKind.CLASS_DECL,
CursorKind.CLASS_TEMPLATE]:
return self._type_definition_fixup()
return self._cache(self._type_definition_fixup)
else:
return self.name

@property
def type(self):
if self._cc.kind in [CursorKind.VAR_DECL, CursorKind.FIELD_DECL]:
return self._var_type_fixup(self)[0]
return self._cache(self._var_type_fixup, self)[0]
if self._cc.kind == CursorKind.FUNCTION_DECL:
return self._function_fixup()
return self._cache(self._function_fixup)
if self._cc.kind in [CursorKind.CONSTRUCTOR,
CursorKind.DESTRUCTOR,
CursorKind.CXX_METHOD,
CursorKind.FUNCTION_TEMPLATE]:
return self._method_fixup()
return self._cache(self._method_fixup)
else:
return self._cc.type.spelling

Expand All @@ -98,13 +106,13 @@ def line(self):
@property
def args(self):
if self._cc.kind == CursorKind.MACRO_DEFINITION:
return self._get_macro_args()
return self._cache(self._get_macro_args)
if self._cc.kind in [CursorKind.FUNCTION_DECL,
CursorKind.CONSTRUCTOR,
CursorKind.DESTRUCTOR,
CursorKind.CXX_METHOD,
CursorKind.FUNCTION_TEMPLATE]:
return self._get_fn_args()
return self._cache(self._get_fn_args)
else:
return None

Expand All @@ -116,7 +124,9 @@ def quals(self):
CursorKind.DESTRUCTOR,
CursorKind.CXX_METHOD,
CursorKind.FUNCTION_TEMPLATE]:
return ' '.join(self._get_method_quals()[1])
def gen(cursor):
return ' '.join(cursor._cache(cursor._get_method_quals)[1])
return self._cache(gen, self)
else:
return None

Expand Down

0 comments on commit fa2f246

Please sign in to comment.