👁️
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

at dev 130 lines 2.7 kB view raw
1/** 2 * Benchmarks for search parsing 3 * 4 * Run with: npm run bench 5 * 6 * Tests the hot path for interactive search-as-you-type. 7 */ 8 9import { bench, describe } from "vitest"; 10import { describeQuery, search } from "../index"; 11import { tokenize } from "../lexer"; 12import { parse } from "../parser"; 13import type { SearchNode } from "../types"; 14 15// Sample queries of varying complexity 16const QUERIES = { 17 simple: "lightning bolt", 18 field: "t:creature", 19 comparison: "mv<=3", 20 multiField: "t:creature mv<=3 c:red", 21 quoted: '"lightning bolt"', 22 exact: '!"Lightning Bolt"', 23 boolean: "t:creature OR t:instant", 24 complex: 't:creature mv<=3 (c:red OR c:blue) -t:legendary o:"deal damage"', 25 regex: "o:/deals? \\d+ damage/", 26 realWorld: "t:creature mv<=2 id<=ug o:counter", 27}; 28 29describe("tokenize (lexer)", () => { 30 bench("simple name", () => { 31 tokenize(QUERIES.simple); 32 }); 33 34 bench("single field", () => { 35 tokenize(QUERIES.field); 36 }); 37 38 bench("multi-field query", () => { 39 tokenize(QUERIES.multiField); 40 }); 41 42 bench("complex boolean", () => { 43 tokenize(QUERIES.complex); 44 }); 45 46 bench("regex pattern", () => { 47 tokenize(QUERIES.regex); 48 }); 49}); 50 51describe("parse (lexer + parser)", () => { 52 bench("simple name", () => { 53 parse(QUERIES.simple); 54 }); 55 56 bench("single field", () => { 57 parse(QUERIES.field); 58 }); 59 60 bench("multi-field query", () => { 61 parse(QUERIES.multiField); 62 }); 63 64 bench("complex boolean", () => { 65 parse(QUERIES.complex); 66 }); 67 68 bench("real-world query", () => { 69 parse(QUERIES.realWorld); 70 }); 71}); 72 73describe("search (full pipeline)", () => { 74 bench("simple name", () => { 75 search(QUERIES.simple); 76 }); 77 78 bench("single field", () => { 79 search(QUERIES.field); 80 }); 81 82 bench("multi-field query", () => { 83 search(QUERIES.multiField); 84 }); 85 86 bench("complex boolean", () => { 87 search(QUERIES.complex); 88 }); 89 90 bench("real-world query", () => { 91 search(QUERIES.realWorld); 92 }); 93}); 94 95// Pre-parse ASTs for describe benchmarks 96function getAst(query: string): SearchNode { 97 const result = parse(query); 98 if (!result.ok) throw new Error(`Failed to parse: ${query}`); 99 return result.value; 100} 101 102const ASTS = { 103 simple: getAst(QUERIES.simple), 104 field: getAst(QUERIES.field), 105 multiField: getAst(QUERIES.multiField), 106 complex: getAst(QUERIES.complex), 107 realWorld: getAst(QUERIES.realWorld), 108}; 109 110describe("describeQuery (AST to text)", () => { 111 bench("simple name", () => { 112 describeQuery(ASTS.simple); 113 }); 114 115 bench("single field", () => { 116 describeQuery(ASTS.field); 117 }); 118 119 bench("multi-field query", () => { 120 describeQuery(ASTS.multiField); 121 }); 122 123 bench("complex boolean", () => { 124 describeQuery(ASTS.complex); 125 }); 126 127 bench("real-world query", () => { 128 describeQuery(ASTS.realWorld); 129 }); 130});