Speedup PP load by caching rules action results on relevant parts of the field.#589
Speedup PP load by caching rules action results on relevant parts of the field.#589pp-mo wants to merge 5 commits intoSciTools:masterfrom
Conversation
|
Context: Analysis of building cubes with rules gave roughly these proportions of time percentage for a simple iris.load_raw call.... This PR addresses the third of these. |
|
Implementation Notes:
|
|
Test results: Testing with a standard test-data file... Results: Speedup on bigger file was larger, up to ~15%. |
|
Future possibility: |
Can I ask for further clarification of the changes made, why is specifying your own shallow and or deep copy operations proving beneficial in your specific case? To be more specific, GeogCS(CoordSystem) I have been looking at. It would be good to capture this reasoning on this ticket in any case for future enhancements or code interpretation. |
There was a problem hiding this comment.
We need a test for each object with shallow/deep copy overrides to ensure that any changes to these objects at present or in future do not result in a malformed 'copy' which may go possibly unnoticed (copying by reference or not when unexpected). An objectA.attribute is not objectB.attribute test for each object attribute would do it I should think for the deep copy overrides.
|
@pp-mo - I've posted a question on the iris-dev discussion group to see how this PR might fit into the bigger picture. |
lib/iris/coord_systems.py
Outdated
There was a problem hiding this comment.
I wouldnt bother putting this into a variable
|
This PR requires #614 to be merged first since unit testing which are to be written as a result of this PR, would likely be affected |
lib/iris/coords.py
Outdated
There was a problem hiding this comment.
coord_system not immutable! your passing by reference here
cannot overemphasize the need for a unittest as described above, for checking that all object components are not references to the original if your overriding deepcopy operations. The others work because they have getter-setter properties.
lib/iris/coords.py
Outdated
There was a problem hiding this comment.
points = self.points
bounds = self.bounds
see comment below for reasoning
|
There are a number of issues identified which require to be addressed before I continue this review. Handing back over to you to address them @pp-mo |
|
It'll be interesting to see what the impact is on performance of the fixes. |
|
re: "Copy the coord_system in Coord deepcopy." (pp-mo@53613dc)
Luckily, it only makes a small difference, presumably as copying coordinate systems was already optimised. |
In offline conversation with @esc24 he expressed some doubts about this way : His view is that 'from_coord' is really just a (somewhat dodgy) way of converting coordinate types (Aux <-> Dim). It probably shouldn't be used for anything else much right now, as we might even want to get rid of it in future. Note: if we do do this, I think we can then implement it at the abstract Coord level. In which case we should also declare from_coord there as an abstract method. The messy almost-identical implementations of from_coord in Dim/Aux would still be needed, but we could at least have just one deepcopy method. |
Just for the complete record.. I speculated that we could consider a CoordSystem 'effectively' immutable, if we disallowed changes to the basic properties (things like 'semi_major_axis', 'longitude_of_prime_meridian' or 'ellipsoid'). |
More... What we are doing here with deepcopy is not a true deepcopy, but relies on design-contract type details. For instance, even the simplest GeogCS.deepcopy is assuming ...
But of course, it is always still possible to attach arbitrary extra attributes (which then won't get copied at all), or define new ones in an inheriting subclass, or replace a 'number' with something else which then might not be immutable (e.g. a numpy scalar??) . One very particular problem with this is that, once you provide a We should probably discuss this with @rhattersley. I can think of at least 3 possible ways forward...
For reference, I added a full deepcopy of all constructor arguments to all the deepcopy overrides provided in this branch, and tested for speed. The result almost exactly cancels out, to give no net speed advantage over un-memoised code. |
|
Good summary @pp-mo. Thanks. |
|
With regards to the I think, move the functionality from |
|
On the above comment of effectively locking down the coord_system to being more or less immutable, I'm with @esc24 on this. We would have to ensure that this wouldnt impact a significant number of users who already make use of this functionality for this route to take place. I think this would effectively put this PR on hold and require a google group discussion if this route were to be taken. |
I'm not proposing it. I just wanted to record why, on reflection, it is not an option. |
|
I think that if using overrides to the deepcopy operation, I would only be happy to do so for possibly private classes, which wont help much here, like you said, a user could very well associate additional information to these objects, its Python after all. Your third option sounds like a possibility. |
|
Addressed most comments, but not all.
|
lib/iris/fileformats/pp.py
Outdated
There was a problem hiding this comment.
...also, since these variables only have relevance to the ppfield, why not define them within there? (again just a thought, might make it neater since the structure then describes where these things tie together). This way, also we can refer to these objects from the subclasses of PPField:
class PPField(object):
_NOCACHE_ELEMENT_NAMES = blabla
_CACHABLE_ELEMENT_NAMES = blabla
_V2_V3_HEADER_VARIANT_NAMES = blabla
def __init__(self):
.................................
Something odd may be happening with Travis. These errors are not happening on the desktop. |
|
A number of change have been made by @rhattersley which may remove some of the benefits of this PR. |
That's no simple task you're suggesting! The rules system has changed considerably since this PR was raised (and in large part, thanks to this very PR), so an equally considerable modification would be required. @pp-mo - in the light of #611, #637, and #642, I'd be very interested to hear your opinion on whether there are improvements made in this PR which have yet to be extracted elsewhere. |
I don't think the subsequent PRs really capture the original intent here. The PRs referred to claim to save about 3% and 10% of a However, even before that degradation, I always felt that a much better win should be possible if result duplication could also be used to speed up the merge process.
So I still think this approach could have very significant benefits, additional to what has already been achieved. But it seems that can only really work if you tackle result construction and merge together. Unfortunately, that wasn't clear when this began (we thought copying would be cheap !!). And, as 'build' and 'merge' were explicitly separated in this investigation, we still don't have even an estimate of what might be achieved that way. |
Captures field accesses on rules action execution (to work out which bits of the field the rule result depends on).
Then caches the relevant result for later re-use, keyed on the field attributes referred to.