Skip to content

DEV build seems to have O(n^2) in registerGraph name resolution for createSignal in onMount when using signals from props #1322

Closed

Description

@tuukkapuranen

Describe the bug

When invoking createSignal multiple times in onMount, there is a noticeable performance degradation in DEV build, when certain conditions are met. Performance recording call tree indicates that the registerGraph function is taking majority of the time.

The registerGraph function creates for a unique name for the signal in DEV builds, and does this in a loop, so I presume the issue is that in some cases the same name is given to the registerGraph for a large number of signals, and the loop has to try all of them every time a new signal is added.

Your Example Website or App

https://stackblitz.com/edit/solid-vite-mmnbja?file=src/index.tsx

Steps to Reproduce the Bug or Issue

  1. Go to https://stackblitz.com/edit/solid-vite-mmnbja?file=src/index.tsx
  2. Wait for component rendering
  3. Observe the duration the onMount function took

Expected behavior

Expected onMount duration is around 10ms, but actual onMount duration is around 3000ms.

Screenshots or Videos

Untitled picture

Platform

  • OS: Windows
  • Browser: Chrome, Edge

Additional context

Note that this issue is only present in DEV build, as the registerGraph is not used in production.

There are several workarounds for this issue. The first seems to be not to use signals from props in onMount, as in https://stackblitz.com/edit/solid-vite-pgsggu?file=src/index.tsx which apparently alters the name generation for the signals in such a way that the issue disappears (in this example, removing the use of props.rows was enough). The second is to use createSignal(false, { internal: true }), which suppresses the name generation for the signal. The third option is to provide unique names for the signals in question, for example createSignal(false, { name: `selectedCells[${row}][${col}]` }).

Activity

  1. LiQuidProQuo commented on Oct 31, 2022

    @LiQuidProQuo
    Contributor

    For Dev when a signal name is generated it uses a rather expensive method(serialization) to generate a hash which may also increase in complexity as the object grows

    export function hashValue(v: any): string {
    const s = new Set();
    return `s${
    typeof v === "string"
    ? hash(v)
    : hash(
    untrack(
    () =>
    JSON.stringify(v, (k, v) => {
    if (typeof v === "object" && v != null) {
    if (s.has(v)) return;
    s.add(v);
    const keys = Object.keys(v);
    const desc = Object.getOwnPropertyDescriptors(v);
    const newDesc = keys.reduce((memo, key) => {
    const value = desc[key];
    // skip getters
    if (!value.get) memo[key] = value;
    return memo;
    }, {} as any);
    v = Object.create({}, newDesc);
    }
    if (typeof v === "bigint") {
    return `${v.toString()}n`;
    }
    return v;
    }) || ""
    )
    )
    }`;
    }

    then if the hash already exists it will loop with an increment until a free name is found

    while (Owner.sourceMap[tryName]) tryName = `${name}-${++i}`;

    The good news is that it's a dev only feature, and performance testing should generally be done on a production build.

  2. ryansolid commented on Oct 31, 2022

    @ryansolid
    Member

    Yeah I've been working with @thetarnav on figuring out if we can just remove all of this. It was an experiment.. seems sort of ill advised at this point. We've found otherways to make dev tools work better.

  3. added this to the 1.7.0 milestone on Mar 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions