@neo4j-cypher/language-support
Version:
Cypher language support
186 lines (174 loc) • 6.15 kB
text/typescript
/* eslint-disable no-console */
import Benchmark from 'benchmark';
import { autocomplete } from '../../autocompletion/autocompletion';
import { parse, parserWrapper } from '../../parserWrapper';
import { signatureHelp } from '../../signatureHelp';
import { applySyntaxColouring } from '../../syntaxColouring/syntaxColouring';
import {
lintCypherQuery,
validateSyntax,
} from '../../syntaxValidation/syntaxValidation';
import { testData } from '../testData';
import {
autocompletionQueries,
createMovieDb,
largePokemonquery,
simpleQuery,
tictactoe,
} from './benchmarkQueries';
const periodicIterate = 'CALL apoc.periodic.iterate(';
const periodicIterateFirstArg = '"MATCH (p:Person) RETURN id(p) as personId", ';
Benchmark.options.minSamples = 10;
Benchmark.options.maxTime = 1;
const suite = new Benchmark.Suite();
suite
.add('simple - parse', function () {
parse(simpleQuery);
})
.add('simple - highlight', function () {
parserWrapper.clearCache();
applySyntaxColouring(simpleQuery);
})
.add('simple - validate syntax', function () {
parserWrapper.clearCache();
validateSyntax(simpleQuery, testData.mockSchema);
})
.add('simple - autocomplete next statement', function () {
parserWrapper.clearCache();
autocomplete(simpleQuery, testData.mockSchema);
})
.add('movies - parse', function () {
parse(createMovieDb);
})
.add('movies - highlight', function () {
parserWrapper.clearCache();
applySyntaxColouring(createMovieDb);
})
.add('movies - validate syntax', function () {
parserWrapper.clearCache();
lintCypherQuery(createMovieDb, testData.mockSchema);
})
.add('movies - autocomplete next statement', function () {
parserWrapper.clearCache();
autocomplete(createMovieDb, testData.mockSchema);
})
.add('movies - signature help', function () {
const subQuery = createMovieDb + periodicIterate;
const query = createMovieDb + periodicIterate + periodicIterateFirstArg;
parserWrapper.clearCache();
signatureHelp(query, testData.mockSchema, query.length - 1);
signatureHelp(query, testData.mockSchema, subQuery.length - 1);
})
.add('tictactoe - parse', function () {
parserWrapper.clearCache();
parse(tictactoe);
})
.add('tictactoe - highlight', function () {
parserWrapper.clearCache();
applySyntaxColouring(tictactoe);
})
.add('tictactoe - validate syntax', function () {
parserWrapper.clearCache();
lintCypherQuery(tictactoe, testData.mockSchema);
})
.add('tictactoe - autocomplete next statement - no Schema', function () {
parserWrapper.clearCache();
autocomplete(tictactoe, {});
})
.add('tictactoe - autocomplete next statement - medium Schema', function () {
parserWrapper.clearCache();
autocomplete(tictactoe, testData.mockSchema);
})
.add('tictactoe - signature help', function () {
const subQuery = tictactoe + periodicIterate;
const query = tictactoe + periodicIterate + periodicIterateFirstArg;
parserWrapper.clearCache();
signatureHelp(query, testData.mockSchema, query.length - 1);
signatureHelp(query, testData.mockSchema, subQuery.length - 1);
})
.add('pokemon - parse', function () {
parserWrapper.clearCache();
parse(largePokemonquery);
})
.add('pokemon - parserwrapper parse', function () {
parserWrapper.clearCache();
parserWrapper.parse(largePokemonquery);
})
.add('pokemon - syntax highlight', function () {
parserWrapper.clearCache();
applySyntaxColouring(largePokemonquery);
})
.add('pokemon - signature help', function () {
const subQuery = largePokemonquery + periodicIterate;
const query = largePokemonquery + periodicIterate + periodicIterateFirstArg;
parserWrapper.clearCache();
// This mimics getting the cursor back in the query and retriggering signature help
signatureHelp(query, testData.mockSchema, query.length);
signatureHelp(query, testData.mockSchema, subQuery.length);
})
.add('multistatement - autocompletion', function () {
const query = tictactoe + ';\n' + tictactoe;
const subQuery = tictactoe;
parserWrapper.clearCache();
// This mimics getting the cursor back in the query and retriggering auto-completion
autocomplete(query, testData.mockSchema);
autocomplete(query, testData.mockSchema, subQuery.length);
});
Object.entries(autocompletionQueries).forEach(([name, query]) => {
suite.add(`autocomplete - ${name} (parse.time.only)`, function () {
parse(query);
});
suite.add(`autocomplete - ${name}`, function () {
parserWrapper.clearCache();
autocomplete(query, testData.mockSchema);
});
});
suite
.on('cycle', function (event: { target: { toString: () => string } }) {
console.log(String(event.target));
})
.on('complete', async function () {
const API_KEY = process.env.GRAFANA_API_KEY;
if (API_KEY) {
console.log('Publishing metrics to grafana');
const USER_ID = 1226722;
const metrics: Record<string, number> = {};
// arcane magic to get the benchmark results
// eslint-disable-next-line
this.forEach(function (benchmark: {
name: string;
hz: number /* operations per second */;
}) {
metrics[benchmark.name] = benchmark.hz;
});
const body = Object.entries(metrics)
.map(
([key, value]) =>
`unit-benchmark,bar_label=${key.replaceAll(
/\s/g,
'',
)},source=benchmarkjs metric=${value}`,
)
.join('\n');
await fetch(
'https://influx-prod-39-prod-eu-north-0.grafana.net/api/v1/push/influx/write',
{
method: 'post',
body,
headers: {
Authorization: `Bearer ${USER_ID}:${API_KEY}`,
'Content-Type': 'text/plain',
},
},
).then((res) => {
if (res.ok) {
console.log('Metrics pushed to grafana successfully');
} else {
throw new Error(
`Failed to push metrics to grafana: ${res.statusText}`,
);
}
});
}
})
.run({ async: true });