-
Notifications
You must be signed in to change notification settings - Fork 9.1k
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
perf: Benchmark nodes-base
#9355
Changes from 3 commits
94f7fbe
98c8938
4c8f903
34efe10
f581e40
4ccef05
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
name: Benchmark | ||
|
||
on: | ||
pull_request: | ||
paths: | ||
- 'packages/cli/**' | ||
- 'packages/core/**' | ||
- 'packages/workflow/**' | ||
- 'packages/nodes-base/**' | ||
workflow_dispatch: | ||
|
||
jobs: | ||
benchmark: | ||
name: Benchmark | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/[email protected] | ||
|
||
- run: corepack enable | ||
|
||
- uses: actions/[email protected] | ||
with: | ||
node-version: 18.x | ||
cache: pnpm | ||
|
||
- run: pnpm install --frozen-lockfile | ||
|
||
- name: Build | ||
if: ${{ inputs.cacheKey == '' }} | ||
run: pnpm build:backend | ||
|
||
- name: Restore cached build artifacts | ||
if: ${{ inputs.cacheKey != '' }} | ||
uses: actions/cache/[email protected] | ||
with: | ||
path: ./packages/**/dist | ||
key: ${{ inputs.cacheKey }} | ||
|
||
- name: Build benchmarks | ||
working-directory: packages/nodes-base | ||
run: pnpm benchmark:build | ||
|
||
- name: Benchmark nodes-base | ||
uses: CodSpeedHQ/action@v2 | ||
with: | ||
working-directory: packages/nodes-base | ||
run: pnpm benchmark:run |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import glob from 'fast-glob'; | ||
import Bench from 'tinybench'; | ||
import { withCodSpeed } from '@codspeed/tinybench-plugin'; | ||
import { setup, workflowToTests as toTests } from './nodes/Helpers'; | ||
import { executeWorkflow } from './nodes/ExecuteWorkflow'; | ||
|
||
async function main() { | ||
const filePaths = await glob('nodes/**/*.workflow.json'); | ||
|
||
console.log(`Found ${filePaths.length} workflows to benchmark`); | ||
|
||
const tests = toTests(filePaths); | ||
const nodeTypes = setup(tests); | ||
const bench = withCodSpeed(new Bench({ time: 0, iterations: 1 })); // @TODO temp config | ||
|
||
for (const test of tests) { | ||
bench.add(test.description, async () => { | ||
await executeWorkflow(test, nodeTypes); | ||
}); | ||
} | ||
|
||
await bench.warmup(); | ||
await bench.run(); | ||
} | ||
|
||
void main(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,7 +38,10 @@ import { executeWorkflow } from './ExecuteWorkflow'; | |
|
||
import { FAKE_CREDENTIALS_DATA } from './FakeCredentialsMap'; | ||
|
||
const baseDir = path.resolve(__dirname, '../..'); | ||
const baseDir = path.resolve( | ||
__dirname, | ||
process.env.NODE_ENV === 'benchmark' ? '../../..' : '../..', | ||
); | ||
|
||
const getFakeDecryptedCredentials = ( | ||
nodeCredentials: INodeCredentialsDetails, | ||
|
@@ -193,6 +196,10 @@ class NodeTypes implements INodeTypes { | |
return this.nodeTypes[nodeType].type; | ||
} | ||
|
||
getKnownTypes(): IDataObject { | ||
return knownNodes; | ||
} | ||
|
||
addNode(nodeTypeName: string, nodeType: INodeType | IVersionedNodeType) { | ||
const loadedNode = { | ||
[nodeTypeName]: { | ||
|
@@ -255,7 +262,10 @@ export function setup(testData: WorkflowTestData[] | WorkflowTestData) { | |
level: 'warning', | ||
}); | ||
} | ||
const sourcePath = loadInfo.sourcePath.replace(/^dist\//, './').replace(/\.js$/, '.ts'); | ||
const sourcePath = | ||
process.env.NODE_ENV === 'benchmark' | ||
? loadInfo.sourcePath | ||
: loadInfo.sourcePath.replace(/^dist\//, './').replace(/\.js$/, '.ts'); | ||
const nodeSourcePath = path.join(baseDir, sourcePath); | ||
const credential = new (require(nodeSourcePath)[loadInfo.className])() as ICredentialType; | ||
credentialTypes.addCredential(credentialName, credential); | ||
|
@@ -270,7 +280,10 @@ export function setup(testData: WorkflowTestData[] | WorkflowTestData) { | |
if (!loadInfo) { | ||
throw new ApplicationError(`Unknown node type: ${nodeName}`, { level: 'warning' }); | ||
} | ||
const sourcePath = loadInfo.sourcePath.replace(/^dist\//, './').replace(/\.js$/, '.ts'); | ||
const sourcePath = | ||
process.env.NODE_ENV === 'benchmark' | ||
? loadInfo.sourcePath | ||
: loadInfo.sourcePath.replace(/^dist\//, './').replace(/\.js$/, '.ts'); | ||
const nodeSourcePath = path.join(baseDir, sourcePath); | ||
const node = new (require(nodeSourcePath)[loadInfo.className])() as INodeType; | ||
nodeTypes.addNode(nodeName, node); | ||
|
@@ -373,6 +386,9 @@ export const workflowToTests = (workflowFiles: string[]) => { | |
); | ||
} | ||
}); | ||
|
||
if (process.env.NODE_ENV === 'benchmark') workflowData.pinData = {}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Benchmarks use This line specifically I added because a handful of workflows (MoveBinaryData, QuickChart) were getting caught by the pindata check right after this line, because they have their own implementation of |
||
|
||
if (workflowData.pinData === undefined) { | ||
throw new ApplicationError('Workflow data does not contain pinData', { level: 'warning' }); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we do a on-the-fly compilation of TS code (like ts-jest does), instead of needing yet another tsconfig? |
||
"extends": ["./tsconfig.json", "../../tsconfig.build.json"], | ||
"compilerOptions": { | ||
"outDir": "dist/test", | ||
"tsBuildInfoFile": "dist/benchmark.tsbuildinfo" | ||
}, | ||
"include": ["test/**/*.ts"], | ||
"exclude": ["test/**/*.test.ts"] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the
> /dev/null
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To silence type errors when transpiling test helpers. Did not fix those here to avoid a larger PR.