question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

v=0.30.1 Multiblock creation/appending is dramatically faster than v=0.32.1 when adding meshes.

See original GitHub issue

A 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:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:15 (15 by maintainers)

github_iconTop GitHub Comments

1reaction
adeakcommented, Nov 15, 2021

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.

1reaction
adeakcommented, Nov 15, 2021

So quick to identify this.

To be fair I haven’t proven it yet, but it’s a very very good guess 😃

Is there anything I can do to help?

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 does self[index] = block, which calls __setitem__.

However __setitem__ ends with https://github.com/pyvista/pyvista/blob/828fa349134e036efac9f47852a1bed4bf51c929/pyvista/core/composite.py#L471-L472

Note that self.refs is a list. So first we do an O(n) sweep over the list to see if the new data is in there. Then if it’s not in there, we call append. Then at the end of MultiBlock.append we do that again… https://github.com/pyvista/pyvista/blob/828fa349134e036efac9f47852a1bed4bf51c929/pyvista/core/composite.py#L336-L337

And there has to be one more leak here:

>>> import pyvista as pv
>>> mb = pv.MultiBlock([pv.Sphere()])
>>> len(mb.refs)
3

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 of object.__eq__ which was blasing-fast based on self is other, this is becoming obvious. We’ll have to refactor MultiBlock to fix this.

Read more comments on GitHub >

github_iconTop Results From Across the Web

No results found

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found