Repository navigation
Speedup of initialization for cosmology objects - #2542
Conversation
* Speed up initialization by about a factor of 100 by pre-computing some unit conversion quantities. It turns out this was the dominant cost, particularly the call to const.G.cgs. * import astropy.cosmology time falls by about 50% * Passes all unit tests * Closes astropy#2479 (sorta; some more sophisticated options were also discussed for that, and this just does the simple bit).
There was a problem hiding this comment.
Should the cgs conversion be done by hand here too?
|
Seems fine to me other than @nhmc's comment. Also note that I killed the first travis build because our queue is getting jammed up, and I figured you really only care about the last one. |
There was a problem hiding this comment.
Also Mpc_km appears to be unused, so can be removed. Not sure how that happened.
|
What I was suggesting is that there are already several properties like Those could be changed to use |
|
In general I think there's way too much "computation" going on in |
|
Maybe that's interesting, but it also now has nothing to do with the original issue, which was that cosmology is slow to import. That isn't entirely fixed, but the things like the fact that |
|
@embray Doing everything in (Sorry, this is getting off topic.) |
|
No, I think you misunderstand what it does. Taking hubble_distance as an example (since it's one of the first such parameters that are computed), it's essentially equivalent to doing this: @property
def hubble_distance(self):
if not hasattr(self, '_hubble_distance'):
self._hubble_distance = hubble_distance = (const.c / self.H0).to(u.Mpc)
return self._hubble_distanceExcept in this case you can write it: @lazyproperty
def hubble_distance(self):
return (const.c / self.H0).to(u.Mpc)Granted this is a relatively trivial example. But the broader point is that currently if one looks at where the @property
def hubble_distance(self):
return self._hubble_distanceand then have to root around for where |
|
@embray - is it alright with you to merge this now so we get the benefits, and adding the |
|
@embray Ah, I understand now. Your example is much clearer example than the one in the |
|
Yeah, perhaps I should just go ahead and make a PR since it was my idea. But at this point it is a separate issue. |
Speedup of initialization for cosmology objects
|
I do like laziness (I play around with Haskell programming on the side), so I think it's a good idea. But we should check the cost of the extra |
|
The lookup is insignificant compared to any other attribute access in Python (in fact there is not literally a Ok0 = self.Ok0
# ... use Ok0 in computation ...for example. |
|
That sounds nice... but doesn't seem to entirely match reality. I tried implementing Ok0, hubble_time, hubble_distance, Ogamma0, and Onu0 as @lazyproperties and comparing the run time on the following: Doing takes 6.33 ms/loop for the current master, but 7.44 ms/loop for the version with This may or may not be acceptable -- it isn't terrible, but a 18% slowdown isn't something we should ignore. The problem is that users are paying all the price for none of the benefits, since the latter are all developer oriented. There may be ways to fix it. Right now the integrals in luminosity_distance use a public function (inv_efunc) to integrate. We could try using an internal version that takes all the Ok0, etc. values as additional arguments, which would avoid whatever I think this makes it clear that speed testing should be included, because the cost is not totally trivial and should be at least acknowledged. BTW, if you are curious, I tried it with |
|
Yes, using an internal version of |
|
I see what you're saying, but the fact remains that if you're really concerned about performance for this breaking it out into a Cython function or something would be ideal. Then we'd be talking about an order of magnitude. |
|
I don't entirely agree with that. You are saying 'we can make this much faster' which is absolutely true. But there's a difference between not taking a (complicated and difficult) opportunity to make something faster vs. doing something for mostly selfish reasons (that is, purely for the benefit of us, the developers) that actually causes a regression. Remember this came up when units were added to cosmology. Kyle, from what I recall, was definitely concerned about slowdowns. And indeed there was some speed cost -- somewhat similar to this -- but at least it benefited the end user. |
|
Yeah, I did some of my own timings and it turns out using That said I'm not entirely convinced that it would be such a bottleneck compared to other issues. Would have to see if it's actually noticeable in use. |
|
Yeah, agreed. I'm not saying to not do this no matter what if there is any slowdown. I'm just asking that when the time comes we do an actual measurement and make sure we're okay with the results. |
|
Sounds good. Definitely for that. FWIW I made some slight speedups in spacetelescope/PyFITS@13d65a8 and will merge them oer here too. It makes |
…peedup Speedup of initialization for cosmology objects
some unit conversion quantities. It turns out this was the
dominant cost, particularly the call to const.G.cgs.
also discussed there, and this just does the simple bit.