Optimize getting config item values #17461
Conversation
|
Thank you for your contribution to Astropy! 🌌 This checklist is meant to remind the package maintainers who will review this pull request of some common things to look for.
|
|
Forgot to add some timings. After: |
| try: | ||
| val = self.value | ||
| except AttributeError: | ||
| val = self.value = self() | ||
| return val |
There was a problem hiding this comment.
What about this?
| try: | |
| val = self.value | |
| except AttributeError: | |
| val = self.value = self() | |
| return val | |
| if not hasattr(self, "value"): | |
| self.value = self() | |
| return self.value |
There was a problem hiding this comment.
try/except has no cost if there is no exception, so I think it is good to use it (hasattr uses it internally, but now you do have the cost of the if statement). I'd try to shave off another few ns with
try:
return self.value
except AttributeError:
self.value = val = self()
return val
There was a problem hiding this comment.
yeah try/except is commonly used in such cases both for perf and also hasattr can have some side effects so simpler is better here.
| try: | ||
| del self.value | ||
| except AttributeError: | ||
| pass |
There was a problem hiding this comment.
Maybe like this instead? Though I don't see how this is equivalent to self.set(self.defaultvalue).
| try: | |
| del self.value | |
| except AttributeError: | |
| pass | |
| if hasattr(self, "value"): | |
| del self.value |
There was a problem hiding this comment.
For self.set(self.defaultvalue) it's annoying but I don't remember 😬 (I really should open PRs faster!)
There was a problem hiding this comment.
note that the try/except form is more robust to parallelism (which might matter in the wake of free-threaded Python ?)
There was a problem hiding this comment.
As long as hitting except is rare...
| @@ -0,0 +1 @@ | |||
| Optimize getting config item values. | |||
There was a problem hiding this comment.
It's not a noticeable change if you get a few config values but it is for io.fits which uses config items when e.g. getting card values. So when reading many keywords or a table with many columns it starts to matter.
There was a problem hiding this comment.
I didn't know FITS uses this... 🙈
mhvk
left a comment
There was a problem hiding this comment.
This looks good to me, though I haven't really looked at this code before, so it would be good for someone else to check too. Benchmarks certainly look good (the one bad one should be an unrelated fluke). But need some precommit fix or so.
mhvk
left a comment
There was a problem hiding this comment.
Nice, looks all good to me.
|
Unfortunately, this caching of config items introduced a bug, in that |
This reverts commit 49765f4.
* Revert "Optimize getting config item values (#17461)" This reverts commit 49765f4. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Fix #12504 (I think, doing better might be possible but not sure without breaking some feature of our complicated configuration system):
As explained there, getting a config item is quite slow, values being stored within the ConfigObj object . And io.fits accesses config items when e.g. accessing the value of a card, this means a lot of config item calls for tables especially with many columns.
So here I'm adding a cache on the ConfigItem descriptor, allowing to get the key much faster while still storing its value on the ConfigObj object.
Description
This pull request is to address ...
Fixes #