Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Few Perf Improvements for kernel startup & more logging #8317

Merged
merged 2 commits into from
Nov 21, 2021
Merged

Conversation

DonJayamanne
Copy link
Contributor

Part of #7849

@DonJayamanne DonJayamanne requested a review from a team as a code owner November 20, 2021 00:44
@@ -94,8 +95,11 @@ export abstract class BaseInstaller {
.get<IPythonInstaller>(IPythonInstaller)
.install(product, resource, cancel, reInstallAndUpdate, installPipIfRequired);
}

public async isInstalled(product: Product, resource?: InterpreterUri): Promise<boolean | undefined> {
@traceDecorators.verbose('Checking if product is installed')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some logging, these were useful

@@ -70,14 +70,14 @@ export type TraceInfo =
export function tracing<T>(log: (t: TraceInfo) => void, run: () => T, logBeforeCall?: boolean): T {
const timer = new StopWatch();
try {
if (logBeforeCall) {
log(undefined);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug fix, we were logging just after the method was called (which was incorrect)

) {
return (notebookMetadata as any).interpreter.hash;
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An unnecessary change, but will be required later.
Had this as part of some other perf fixes that I'm not submitting just yet, basically moved the extraction of interpreterHash from notebook metadata into a function.

@inject(IDisposableRegistry) disposables: IDisposableRegistry,
@inject(IMemento) @named(GLOBAL_MEMENTO) private readonly globalState: Memento
) {
this.envVarsProvider.onDidEnvironmentVariablesChange(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clear the cache if user updates their env variables


/**
* This should return a WRITABLE place that jupyter will look for a kernel as documented
* here: https://jupyter-client.readthedocs.io/en/stable/kernels.html#kernel-specs
*/
@traceDecorators.verbose('Getting Jupyter KernelSpec Root Path')
public async getKernelSpecRootPath(): Promise<string | undefined> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

THis logging was very useful,
On windows this is very slow as tryGetRealPath is slow in windows.
Caching takes only 15-20ms and without that it takes around 400ms on windows, every time. this gets called at least 3 times, thus we shaved well over 1s with this simple change.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't you have some decorator way to cache results from a function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes, yo'ure right, let me check

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing decorator will not , because that uses a memory based cache store, i.e. when user reloads VS Code the cache is empty.

I'd need to create a decorator that uses the global memento? Would definitely make the code cleaner & improve readability.
Will do that next week (I.e. will not merge this PR).

@@ -76,27 +104,41 @@ export class JupyterPaths {
* We need to look at the 'kernels' sub-directory and these paths are supposed to come first in the searching
* https://jupyter.readthedocs.io/en/latest/projects/jupyter-directories.html#envvar-JUPYTER_PATH
*/
@traceDecorators.verbose('Get Jupyter Paths')
private async getJupyterPathPaths(cancelToken?: CancellationToken): Promise<string[]> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logging and caching was very useful, see comments earlier.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment on this one. I swear you had something that would cache results for a function call into a memento.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes now I remember, we had code to cache in memento, I think its in the Python extension, & it may have been removed from this repo as it wasn't used.

@@ -391,7 +391,7 @@ export class NotebookControllerManager implements INotebookControllerManager, IE

// Prep so that we can track the selected controller for this document
traceInfoIfCI(`Clear controller mapping for ${getDisplayPath(document.uri)}`);
const loadControllersPromise = this.loadNotebookControllers();
void this.loadNotebookControllers();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its ok if the controllers haven't loaded,
We can create the controllers as required.
After all, that's what we do, we get controller information and create the controller.
If we call that again its not re-created.

This way, we don't have to wait for all 10-20 or 50 controllers to get loaded.
I.e. we can create controllers one by one based on the information available.

Result, we can now run button will be available even earlier.

Got more changes that will imporve this scenario & make this change all the more useful (separate PR).

);
// Possible the kernel discovery hasn't completed yet.
if (preferredConnection) {
this.createNotebookControllers([preferredConnection]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If not available, then just create it.

@@ -34,7 +33,7 @@ export class PythonKernelLauncherDaemon implements IDisposable {
@inject(KernelEnvironmentVariablesService)
private readonly kernelEnvVarsService: KernelEnvironmentVariablesService
) {}
@traceDecorators.verbose('Launching kernel daemon', TraceOptions.BeforeCall)
@traceDecorators.verbose('Launching kernel daemon')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TraceOptions.BeforeCall is the default, hence removed this in a few places

@codecov-commenter
Copy link

Codecov Report

Merging #8317 (b95e8f0) into main (8734a9b) will increase coverage by 0%.
The diff coverage is 74%.

@@          Coverage Diff          @@
##            main   #8317   +/-   ##
=====================================
  Coverage     72%     72%           
=====================================
  Files        372     372           
  Lines      23232   23259   +27     
  Branches    3553    3558    +5     
=====================================
+ Hits       16784   16817   +33     
+ Misses      4998    4996    -2     
+ Partials    1450    1446    -4     
Impacted Files Coverage Δ
...rc/client/common/process/pythonExecutionFactory.ts 79% <ø> (ø)
...atascience/kernel-launcher/kernelLauncherDaemon.ts 90% <ø> (-1%) ⬇️
...client/datascience/kernel-launcher/jupyterPaths.ts 73% <67%> (+5%) ⬆️
src/client/common/installer/productInstaller.ts 62% <100%> (+<1%) ⬆️
src/client/common/process/processFactory.ts 90% <100%> (+<1%) ⬆️
src/client/common/utils/misc.ts 63% <100%> (ø)
src/client/datascience/jupyter/kernels/helpers.ts 72% <100%> (+<1%) ⬆️
...nt/datascience/kernel-launcher/kernelDaemonPool.ts 88% <100%> (ø)
...lient/datascience/kernel-launcher/kernelProcess.ts 71% <100%> (ø)
src/client/debugger/jupyter/kernelDebugAdapter.ts 82% <0%> (-1%) ⬇️
... and 5 more

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants