Skip to content

Commit

Permalink
minor optimisations (#4549)
Browse files Browse the repository at this point in the history
* minor optimisations

* avoid unncecessary dict update

* whatsnew entry
  • Loading branch information
bjlittle authored Jan 28, 2022
1 parent 6bdc6d5 commit 53c93cb
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 26 deletions.
4 changes: 4 additions & 0 deletions docs/src/whatsnew/latest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ This document explains the changes made to Iris for this release
:class:`benchmarks.HorizontalChunkedRegridding` shows a time decrease
from >10s to 625ms. (:issue:`4280`, :pull:`4400`)

#. `@bjlittle`_ included an optimisation to :class:`~iris.cube.Cube.coord_dims`
to avoid unnecessary processing whenever a coordinate instance that already
exists within the cube is provided. (:pull:`4549`)


🔥 Deprecations
===============
Expand Down
7 changes: 4 additions & 3 deletions lib/iris/_merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -1809,7 +1809,8 @@ def key_func(coord):

# Order the coordinates by hints, axis, and definition.
for coord in sorted(coords, key=key_func):
if not cube.coord_dims(coord) and coord.shape == (1,):
dims = tuple(cube.coord_dims(coord))
if not dims and coord.shape == (1,):
# Extract the scalar coordinate data and metadata.
scalar_defns.append(coord.metadata)
# Because we know there's a single Cell in the
Expand All @@ -1834,11 +1835,11 @@ def key_func(coord):
# Extract the vector coordinate and metadata.
if id(coord) in cube_aux_coord_ids:
vector_aux_coords_and_dims.append(
_CoordAndDims(coord, tuple(cube.coord_dims(coord)))
_CoordAndDims(coord, dims)
)
else:
vector_dim_coords_and_dims.append(
_CoordAndDims(coord, tuple(cube.coord_dims(coord)))
_CoordAndDims(coord, dims)
)

factory_defns = []
Expand Down
60 changes: 37 additions & 23 deletions lib/iris/cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -1451,39 +1451,53 @@ def coord_dims(self, coord):
The (name of the) coord to look for.
"""

coord = self.coord(coord)

# Search for existing coordinate (object) on the cube, faster lookup
# than equality - makes no functional difference.
matches = [
(dim,)
for coord_, dim in self._dim_coords_and_dims
if coord_ is coord
]
if not matches:
matches = [
dims
for coord_, dims in self._aux_coords_and_dims
if coord_ is coord
]

# Search derived aux coords
if not matches:
name_provided = False
if isinstance(coord, str):
# Forced to look-up the coordinate if we only have the name.
coord = self.coord(coord)
name_provided = True

coord_id = id(coord)

# Dimension of dimension coordinate by object id
dims_by_id = {id(c): (d,) for c, d in self._dim_coords_and_dims}
# Check for id match - faster than equality check
match = dims_by_id.get(coord_id)

if match is None:
# Dimension/s of auxiliary coordinate by object id
aux_dims_by_id = {id(c): d for c, d in self._aux_coords_and_dims}
# Check for id match - faster than equality
match = aux_dims_by_id.get(coord_id)
if match is None:
dims_by_id.update(aux_dims_by_id)

if match is None and not name_provided:
# We may have an equivalent coordinate but not the actual
# cube coordinate instance - so forced to perform coordinate
# lookup to attempt to retrieve it
coord = self.coord(coord)
# Check for id match - faster than equality
match = dims_by_id.get(id(coord))

# Search derived aux coordinates
if match is None:
target_metadata = coord.metadata

def match(factory):
def matcher(factory):
return factory.metadata == target_metadata

factories = filter(match, self._aux_factories)
factories = filter(matcher, self._aux_factories)
matches = [
factory.derived_dims(self.coord_dims) for factory in factories
]
if matches:
match = matches[0]

if not matches:
if match is None:
raise iris.exceptions.CoordinateNotFoundError(coord.name())

return matches[0]
return match

def cell_measure_dims(self, cell_measure):
"""
Expand Down

0 comments on commit 53c93cb

Please sign in to comment.