Skip to content

Commit 6117f60

Browse files
authored
Speed up Cube.subset/Coord.intersect (#4955)
* Speed up Cube.subset/Coord.intersect * Add a whatsnew entry
1 parent 379c098 commit 6117f60

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

docs/src/whatsnew/latest.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ This document explains the changes made to Iris for this release
8282
:meth:`iris.cube.Cube.subset`, and :meth:`iris.coords.Coord.intersect`.
8383
(:pull:`4969`)
8484

85+
#. `@bouweandela`_ improved the speed of :meth:`iris.cube.Cube.subset` /
86+
:meth:`iris.coords.Coord.intersect`.
87+
(:pull:`4955`)
88+
8589
🔥 Deprecations
8690
===============
8791

lib/iris/coords.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,7 +1344,14 @@ def __add__(self, mod):
13441344
return Cell(point, bound)
13451345

13461346
def __hash__(self):
1347-
return super().__hash__()
1347+
# See __eq__ for the definition of when two cells are equal.
1348+
if self.bound is None:
1349+
return hash(self.point)
1350+
bound = self.bound
1351+
rbound = bound[::-1]
1352+
if rbound < bound:
1353+
bound = rbound
1354+
return hash((self.point, bound))
13481355

13491356
def __eq__(self, other):
13501357
"""
@@ -2374,18 +2381,16 @@ def intersect(self, other, return_indices=False):
23742381
)
23752382
raise ValueError(msg)
23762383

2377-
# Cache self.cells for speed. We can also use the index operation on a
2378-
# list conveniently.
2379-
self_cells = [cell for cell in self.cells()]
2384+
# Cache self.cells for speed. We can also use the dict for fast index
2385+
# lookup.
2386+
self_cells = {cell: idx for idx, cell in enumerate(self.cells())}
23802387

23812388
# Maintain a list of indices on self for which cells exist in both self
23822389
# and other.
23832390
self_intersect_indices = []
23842391
for cell in other.cells():
2385-
try:
2386-
self_intersect_indices.append(self_cells.index(cell))
2387-
except ValueError:
2388-
pass
2392+
if cell in self_cells:
2393+
self_intersect_indices.append(self_cells[cell])
23892394

23902395
if return_indices is False and self_intersect_indices == []:
23912396
raise ValueError(

lib/iris/tests/test_cell.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,35 @@ def test_coord_bounds_cmp(self):
169169
self.assertTrue(self.e < 2)
170170

171171
def test_cell_cell_cmp(self):
172+
self.e = iris.coords.Cell(1)
173+
self.f = iris.coords.Cell(1)
174+
175+
self.assertTrue(self.e == self.f)
176+
self.assertEqual(hash(self.e), hash(self.f))
177+
178+
self.e = iris.coords.Cell(1)
179+
self.f = iris.coords.Cell(1, [0, 2])
180+
181+
self.assertFalse(self.e == self.f)
182+
self.assertNotEqual(hash(self.e), hash(self.f))
183+
184+
self.e = iris.coords.Cell(1, [0, 2])
185+
self.f = iris.coords.Cell(1, [0, 2])
186+
187+
self.assertTrue(self.e == self.f)
188+
self.assertEqual(hash(self.e), hash(self.f))
189+
190+
self.e = iris.coords.Cell(1, [0, 2])
191+
self.f = iris.coords.Cell(1, [2, 0])
192+
193+
self.assertTrue(self.e == self.f)
194+
self.assertEqual(hash(self.e), hash(self.f))
195+
172196
self.e = iris.coords.Cell(0.7, [1.1, 1.9])
173197
self.f = iris.coords.Cell(0.8, [1.1, 1.9])
174198

199+
self.assertFalse(self.e == self.f)
200+
self.assertNotEqual(hash(self.e), hash(self.f))
175201
self.assertFalse(self.e > self.f)
176202
self.assertTrue(self.e <= self.f)
177203
self.assertTrue(self.f >= self.e)

0 commit comments

Comments
 (0)