Skip to content

Performance improvements for astropy.units - #2544

Merged
eteq merged 3 commits into
astropy:masterfrom
mdboom:unit/performance2
May 26, 2014
Merged

eteq merged 3 commits into
astropy:masterfrom
mdboom:unit/performance2

Conversation

@mdboom

@mdboom mdboom commented May 21, 2014

Copy link
Copy Markdown
Contributor
  • For compose, the set of destination units are prefiltered to only
    include units that have bases in common with "self". This cuts down
    on the search space considerably in most cases.
  • Inline some delegation functions.
  • Replace 2 isinstance calls with 1
  • Cache the hash of composite units, which can be expensive to compute.

This is partially in response to #2479, though it probably makes sense to also include #2542 as well (though this and #2542 are completely independent).

- For compose, the set of destination units are prefiltered to only
  include units that have bases in common with "self".  This cuts down
  on the search space considerably in most cases.

- Inline some delegation functions.

- Replace 2 isinstance calls with 1

- Cache the hash of composite units, which can be expensive to compute.
@mdboom mdboom added this to the v0.4.0 milestone May 21, 2014
@eteq

eteq commented May 21, 2014

Copy link
Copy Markdown
Member

So the reason why it's safe to cache the hash (say that 3 times fast...) is because CompositeUnits are immutible after creation, is that right, @mdboom? And if so, I wonder if it might make sense to short-cut even further by having a CompositUnit._cached_hashes dict? That is, it would take a key (self._scale, self._bases, self._powers) and give back the hash as computed here? Then even if you're constantly making new instances via e.g. u.km/u.s, it will still shortcut the hash?

@mdboom

mdboom commented May 21, 2014

Copy link
Copy Markdown
Contributor Author

Yes -- this works because they are immutable.

I don't think there'd be any benefit to having a global dictionary of hashes as you describe, since you'd have to compute the hash to get the hash anyway.

@eteq

eteq commented May 22, 2014

Copy link
Copy Markdown
Member

Oh, duh, good point. I guess dictionaries aren't just magic, after all...

Also, note that I canceled the travis build on 3143b82 because our queue is really jammed up (and it's just a changelog updating commit)

EDIT: now that I think about it, it probably would have made more sense to kill the earlier one... but it shouldn't matter here because the changelog change is trivial

Comment thread astropy/units/core.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cgs and si could just as well use @lazyproperty rather than saving it explicitly off to an attribute (ultimately the same thing just gets rid of a little boilerplate).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I had forgotten about lazyproperty.

Comment thread astropy/units/core.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mdboom - I'm still not completely sure how this is supposed to work, but think you may need to deal with the tunit is None case as well. Likely, the only equivalency to use this will remain dimensionless_angles, and for this case, if, e.g., other has radian as a base, while self does not, should one not conclude this is a fair base to try?

I guess without further looking into this, I would suggest adding a test case:

u.Unit("rad/s").compose(units=(u.day,), equivalencies=u.dimensionless_angles())

but looking at the current master, this fails, so perhaps this is outside of the scope of this PR (if you think so, I'll make a separate issue).

@eteq

eteq commented May 26, 2014

Copy link
Copy Markdown
Member

Is this all set, @mdboom, or do you think you need to address @mhvk's comment in this PR?

@mhvk

mhvk commented May 26, 2014

Copy link
Copy Markdown
Contributor

@eteq, @mdboom: on further thought, I think my comment really should be a separate issue, so I raised one (#2559); note that it has started me to wonder why we allow equivalencies in compose at all -- it seems to behave more than a little weirdly...

@eteq

eteq commented May 26, 2014

Copy link
Copy Markdown
Member

Alright, in that case I'll just go ahead and merge this, as the tests are all happy.

eteq added a commit that referenced this pull request May 26, 2014
Performance improvements for astropy.units
@eteq
eteq merged commit 593bece into astropy:master May 26, 2014
eteq added a commit that referenced this pull request May 26, 2014
@mdboom

mdboom commented May 27, 2014

Copy link
Copy Markdown
Contributor Author

compose is used by find_equivalent_units, so by definition, should be equivalencies aware... Plus, it's useful if you want to recompose units into some indirectly equivalent units. It already works in some cases, but not in the general case, and it was never updated properly when the convention of being equivalent to the dimensionless unit was added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Affects-dev PRs and issues that do not impact an existing Astropy release units

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants