-
-
Notifications
You must be signed in to change notification settings - Fork 336
Description
Please read the FAQ for the bug you encountered.
- I have read the existing FAQ
β― Playground Link
The playground is too big to share.
π» Code
Reproduction repo: https://github.com/Timeless0911/ast-grep-matcher-performance
Reproduction steps:
pnpm ipnpm build
In Rslib, I use below matcher to find out the import and require statement in DTS files.
const matcher: NapiConfig = {
rule: {
kind: "string_fragment",
any: [
{
inside: {
stopBy: "end",
kind: "import_statement",
field: "source",
},
},
{
inside: {
stopBy: "end",
kind: "export_statement",
field: "source",
},
},
{
inside: {
kind: "string",
inside: {
kind: "arguments",
inside: {
kind: "call_expression",
has: {
field: "function",
regex: "^(import|require)$",
},
},
},
},
},
],
},
};The usage is like below:
const content = await fsP.readFile(dtsFile, 'utf-8');
const sgNode = (await parseAsync('typescript', content)).root();
const matchModule = sgNode.findAll(matcher).map((matchNode) => {
return {
n: matchNode.text(),
s: matchNode.range().start.index,
e: matchNode.range().end.index,
};
});I found that there are some performance issues when in large files with some inline import/require statements.
π Actual behavior
In repro demo, I use four files to test and the result is as below:
File: ./file/less-import-no-format.d.ts, Time: 228ms
File: ./file/less-import-format.d.ts, Time: 187ms
File: ./file/much-import-no-format.d.ts, Time: 7119ms
File: ./file/much-import-format.d.ts, Time: 2228ms
less-import-no-format.d.ts: 4161 lines withimportstatement only in few lines of the headless-import-format.d.ts: 11415 lines with formatter applying inless-import-format.d.tsmuch-import-no-format.d.ts: 4161 lines with manyimportstatement in lines
import: import("zod").ZodUnion<[import("zod").ZodString, import("zod").ZodArray<import("zod").ZodString, "many">]>;much-import-format.d.ts: 12401 lines with formatter applying inmuch-import-no-format.d.ts
π Expected behavior
All files without formatter applied be completed in as fast as possible to hundred ms.
Additional information about the issue
Whether or not to format is a factor that I found to affect the time.
In addition, I also divided the matcher into two parts and found that stopBy: "end" is the main reason affecting performance.
{
inside: {
+ stopBy: "end",
kind: "import_statement",
field: "source",
},
},I need to match these import/require statements:
import { foo } from "bar";
export { foo } from "bar";
require("bar");
import("bar");I don't know if you have any suggestions on this issue, many thanks!