Skip to content

Performance regression in 0.20 #3024

@WorldSEnder

Description

@WorldSEnder

js-framework-benchmark shows a serious problem in the "create many rows" benchmark. My initial analysis points to the following method appear way too often on the stacktrace (recursively):

impl PartialEq for NodeRef {
fn eq(&self, other: &Self) -> bool {
self.0.as_ptr() == other.0.as_ptr() || Some(self) == other.0.borrow().link.as_ref()
}
}

I believe the check in NodeRef::link causes a very long chain of linked node refs to be traversed. I'm not certain yet why such a long chain exists in the first place. It might be connected to a specific order in which the lifetime methods of components are called. Before a component is rendered, a node ref is still created and linked to its successor. This could cause such a huge chain, and most likely O(n^2) behaviour in large lists.

Why does it not show up in our benchmarks? The regression might have been introduced before these were established.


Anyway, I'll see if I can come up with a fix. This might be the time to rework NodeRefs overall. The current design seems especially vulnerable to this accidental n^2 behaviour.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions