v=0.30.1 Multiblock creation/appending is dramatically faster than v=0.32.1 when adding meshes.
See original GitHub issueA minimally reproducible example can be used below for testing.
import pyvista as pv
import numpy as np
from time import perf_counter as pf
def create_spline():
line = np.random.randint(0, 100, (20, 3))
spline = pv.Spline(line)
tube = spline.tube(radius=1)
return tube
splines = [create_spline() for _ in range(1000)]
t = pf()
block = pv.MultiBlock(splines)
mesh = block.combine()
print (pf() - t)
mesh.plot()
The choice of a tube mesh can be replaced here with any other mesh and the problem still persists.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:1
- Comments:15 (15 by maintainers)
Top Results From Across the Web
No results found
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
First take: https://github.com/pyvista/pyvista/pull/1805. We should get this right so I don’t expect it to be merged too soon. We’ll have to make sure we’re not breaking something or missing important corner cases.
To be fair I haven’t proven it yet, but it’s a very very good guess 😃
Probably not, but the fact that you’ve flagged this is already huge help for us 😃 Thank you.
Looking at the implementation of MultiBlock, there are multiple things that jump out at me. When you initialise a MultiBlock from a sequence of meshes,
.append
is called with each mesh. In turn this doesself[index] = block
, which calls__setitem__
.However
__setitem__
ends with https://github.com/pyvista/pyvista/blob/828fa349134e036efac9f47852a1bed4bf51c929/pyvista/core/composite.py#L471-L472Note that
self.refs
is a list. So first we do anO(n)
sweep over the list to see if the new data is in there. Then if it’s not in there, we callappend
. Then at the end ofMultiBlock.append
we do that again… https://github.com/pyvista/pyvista/blob/828fa349134e036efac9f47852a1bed4bf51c929/pyvista/core/composite.py#L336-L337And there has to be one more leak here:
The first two items are the mesh itself, and the third item is the mesh in a one-element tuple…
So there’s a lot of cruft in the implementation, and now that membership comparison triggers the new heavy
__eq__
instead ofobject.__eq__
which was blasing-fast based onself is other
, this is becoming obvious. We’ll have to refactorMultiBlock
to fix this.