-
Notifications
You must be signed in to change notification settings - Fork 4
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
Optimise the execution time of PK CLI calls by not importing the entire kitchen sink #277
Comments
Using this: var Module = require('module');
var __require = Module.prototype.require
Module.prototype.require = function(id) {
var ts = process.hrtime();
var res = __require.call(this, id);
var t = process.hrtime(ts);
var ms = t[0]*1000 + t[1]/1e6;
if (ms > 50) {
console.log(
'require(\'%s\') took %s ms',
id,
t[0]*1000 + t[1]/1e6
);
}
return res;
} Put it on top of We get:
Firstly... why is Interesting that the Inspecting it tells us that the combination of |
We will need to add this to our benchmarks so we can track this over time. One problem with the above hack is that we cannot see the full path of the module. Since the |
The So if all together the It seems the problem can be resolved if we ensure that the Alternatively during the packaging, it will be required to run a tree-shaking minifier to ensure that the CLI scripts aren't loading useless things. There are some options: |
pk --help
We can try using dynamic imports. That way, things only imported when the action handler is called. https://javascript.info/modules-dynamic-imports. @tegefaulkes mentioned that commander has another way of constructing all the commands. We also need to make our Compare this to other compiled program executions like Our baseline is the node runtime, which takes about 32ms to run a Note that MatrixAI/TypeScript-Demo-Lib#32 is about using dynamic imports along with other advanced features in order do feature-tests and importing different implementations based on different platforms. However dynamic imports is already available now, so we start to make use of it in our |
Commander has stand alone executable for sub commands. https://www.npmjs.com/package/commander#stand-alone-executable-subcommands |
The standalone commands might work with the scripts option in pkg.
But even import expressions may need pkg configuration if they have variable inputs.
Best to try it out on TS demo lib.
On 29 October 2021 12:34:09 pm AEDT, Brian Botha ***@***.***> wrote:
Commander has stand alone executable for sub commands. https://www.npmjs.com/package/commander#stand-alone-executable-subcommands
However this means we would need multiple executable files for the final program. I'm not sure how well that will work with pkg either.
--
You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub:
#277 (comment)
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
|
It turns out |
Important to ensure that all utilities imported statically aren't importing everything in the application. Watch out for Benchmarks on bin code can watch out for performance regressions! |
With the merging of https://gitlab.com/MatrixAI/Engineering/Polykey/js-polykey/-/merge_requests/213. All commands are using dynamic imports. We should measure the execution speed of the bin CLI calls again. |
With the addition of the typescript compiler cache, execution times for the pk CLI is approaching acceptable speeds now. Will close this issue for now until we get some problems. Overall benchmarks can be done in a later PR that takes into account the entire application. |
Specification
From reviewing https://gitlab.com/MatrixAI/Engineering/Polykey/js-polykey/-/merge_requests/213 I discovered that it was taking 9 seconds to run the
npm run polykey -- -h
. This was optimised to a bit above 6 seconds when using--transpile-only
.However then I wanted to know what happens when the code is fully compiled. After running
npm run build
andnode ./dist/bin/polykey -h
it still showed about0.55s
for real time.Now taking about half a second to show the help page is bad UX. It also potentially indicates that our application is slow for some reason.
Playing around with disabling the require/imports in the compiled js
dist
and also using the0x
flamegraph seems to indicate that any of the imports going into Polykey results in almost importing the entire application and this contributes to about 400ms of execution time. Our import graph is quite loopy right now to due mutually recursive imports in PK. Usually this would not be a problem in a compiled language where all the code was ultimately in the same executable image. However here, we should look into optimising this so that we can have a cleaner and leaner code. I'm curious what the perf will be once we package it invercel/pkg
.However this doesn't tell us whether it's just due to importing so many files that gradually builds up to 400ms or is there something going in one or two or more particular files that is causing the slowdown.
Tracing the
require
will tell us this. This https://stackoverflow.com/questions/20671222/how-can-i-log-all-requires-in-node-js tells us how to monkey patch therequire
call and can give us a log of all the code being required and how long they are taking to do so.Additional context
0x dist/bin/polykey.js -h
:Tasks
ts-node
to use--transpile-only
option for thepolykey
command but not thets-node
command fornpm
.src/errors.ts
which imports all other errors. But errors should be not be importing any utilities and so they should be a self-contained mutual recursion.0.035s
, which is about 34ms. So I reckon showing the help page should only take about 100ms, instead of the current 550ms.The text was updated successfully, but these errors were encountered: