Skip to content

Performance Improvements using Worker Threads #15813

Closed as not planned
Closed as not planned

Description

I've been looking into a performance issue related to opening notebook.
TLDR - Opening a notebook in widows for Chris Dias and me takes 20-30 seconds (Jupyter extension is not doing anything).
If we disable the Python extension, it opens almost immediately (~5 seconds).

I think the delay is in Python extension spawning n processes. I know we're making changes to environment discovery.
However I think we can improve this even further (or, even with the current changes, it might not be sufficient).

I believe the problem lies with the spawning of processes, if we spawn proceses, it takes a few ms to just spawn the process, e.g. i know on Windows, spawning a conda process takes a few seconds, & that's blocking (spawning processes in node is synchronous) - but communication is async.

This blocks the main thread, hence blocks all other extensions (kinda explains why it takes so many seconds to just open a notebook when Jupyter isn't doing anything).

Suggestion - Why not spawn the processes in a worker thread (completely non-blocking)
I did look into this last year, & we can do this today.

What can we move to these worker threads:
Spawning processes just to get their environment information
Spawning processes to run code e.g. python -c "import ipykernel"
& other simple processes

Activity

  1. added
    bugIssue identified by VS Code Team member as probable bug
    triage-neededNeeds assignment to the proper sub-team
    on Mar 30, 2021
  2. karthiknadig commented on Mar 30, 2021

    @karthiknadig
    Member

    Don Jayamanne (@DonJayamanne) we should turn this into a meta issue an create work items for each particular case we move into worker. This is great if we can do this where ever possible.

  3. added
    metaIssue that is tracking an overall project
    and removed
    triage-neededNeeds assignment to the proper sub-team
    on Mar 30, 2021
  4. DonJayamanne commented on Apr 2, 2021

    @DonJayamanne
    Author

    FYI - We have managed to resolve the performance issue in Jupyter notebooks by delaying the loading of the Python extension. Now Jupyter Notebooks open in around 3 seconds, basically the Python extension gets loaded/activated AFTER the notebook is opened.
    Hence this isn't a priority anymore, but if we had this, we'd ensure the Jupyter extension doesn't regress & we don't need to worry about other extensions blocking us. (or this extenison not blocking others)

  5. Tyriar commented on Sep 15, 2023

    @Tyriar

    Looking briefly at how the locators work I believe you could make this much faster if you performed this and other similar functions in parallel:

    public async *iterEnvs(query?: PythonLocatorQuery): IPythonEnvsIterator<BasicEnvInfo> {
    await this.activate();
    const iterator = this.doIterEnvs(query);
    if (query?.envPath) {
    let result = await iterator.next();
    while (!result.done) {
    const currEnv = result.value;
    const { path } = getEnvPath(currEnv.executablePath, currEnv.envPath);
    if (arePathsSame(path, query.envPath)) {
    yield currEnv;
    break;
    }
    result = await iterator.next();
    }
    } else {
    yield* iterator;
    }
    }

    I may just not be understanding things but from what I hear, environment discovery can take 20 seconds which seems like an outrageous amount of time to me. Have we done a perf trace to see where time is actually being spent when the environment activation is happening?

    I believe the problem lies with the spawning of processes, if we spawn proceses, it takes a few ms to just spawn the process, e.g. i know on Windows, spawning a conda process takes a few seconds, & that's blocking (spawning processes in node is synchronous) - but communication is async.

    Processes should block main for milliseconds, spawning a single conda process certainly should not be blocking the extension host for seconds.

  6. DonJayamanne commented on Sep 16, 2023

    @DonJayamanne
    Author

    Processes should block main for milliseconds, spawning a single conda process certainly should not be blocking the extension host for seconds.

    yes that’s correct
    conda takes 20 seconds but that doesn’t block node, I should have been more clear
    I found using worker threads to be an improvement, at least that’s when I prototyped the code

  7. Tyriar commented on Sep 16, 2023

    @Tyriar

    I had a chat with Kartik Raj (@karrtikr) yesterday and it looks like there's some pretty nice gains to be made by making locators run more in parallel.

  8. karrtikr commented on Nov 15, 2023

    @karrtikr

    Closing in favor of #22146 (comment).

  9. locked as resolved and limited conversation to collaborators on Dec 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area-editor-*User-facing catch-allbugIssue identified by VS Code Team member as probable bugmetaIssue that is tracking an overall project

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions