Repository navigation
typescript rules: the three shapes the profile named — 192s → 99s serial solve on a 1.1M-LOC subject - #1860
Conversation
…rial on a 1.1M-LOC subject The souffle profile on a 4,461-file TypeScript subject put ~85s of a 192s serial solve in three shapes, each the TypeScript twin of one the Java engine already fixed: - qualified_name_binds matched the import qualifier by SUBSTRING against every demanded dotted name: no index applies, |demanded| x |bindings| pairs with two substr calls each — 29s for 805 rows, the most expensive rule of the solve. An import's local name holds no dot, so the qualifier is exactly one of the name's dot-prefixes, and qname_dot_prefix (written for the same lesson one rule above) already enumerates those: joined by equality, probed through the index. The qname_walk seed with the same body is joined the same way — two dot-prefixes of one demanded name nest, so the substring tests were implied. - name_binds and name_binds_any enumerated |client modules| x |demanded names| in front of global_decl_visible, which already holds exactly the gated (module, name) pairs — 30s between the twins. Anchored on the table; the module_decl check stays as an indexed probe. - a property access was decomposed inline — the PROPERTY_ACCESS scan, its name, its RECEIVER child — in 22 rules, most recursive through expr_type(receiver), and semi-naive evaluation re-anchored that scan every iteration (expr_type's clauses: all of their time recursive, 17K tuples/s). property_access_recv materializes the three atoms once, below the typing fixpoint; the 22 rules start from their delta and probe it by receiver. No semantic change, and the gate proves it: every output relation of the old and new engine is BYTE-identical on the 1,266-file subject and on the 4,461-file one, same facts, same machine. Serial solve: 13.3s -> 9.4s (-29%) small, 192s -> 99s user (-48%) large. tests/run.py --lang typescript: 237 of 262, the same 25 const-object checks that fail on the base. run-souffle.sh learns AXIOM_DL_PROFILE=<file>: the solve runs once in the souffle interpreter with per-rule profiling to <file> — how these rules were found, kept for the next language. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
|
Round 2 attempted two further hoists (the Round 2 is reverted; this PR stays at round 1 (−48% serial solve, byte-identical on both subjects). The remaining profile tail is flat (≤3.6s/rule), so further rule work should start from that fixture, not from more hoists. |
…object shape The round-2 rule hoists lost exactly this edge — attachTo.parent.getHash(), the receiver typed by a shape's field — degrading it to ambiguous_unknown while all 262 existing checks held; only the byte-identity A/B gate saw it. The 2-file shape is now a case, so the next rule reordering in the field-access neighborhood fails a named check instead of a diff. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
The TypeScript counterpart of the Java rule work (243a4b2), found the same way: an instrumented souffle solve on a 4,461-file subject, per-rule times, then the three worst shapes restructured with tuple-identical semantics.
qualified_name_binds+ theqname_walkseedqname_dot_prefix(the fix one rule above already recorded; two clauses never adopted it)name_binds,name_binds_anyglobal clausesglobal_decl_visible, which already holds the gated (module, name) pairsproperty_access_recvmaterialized once below the fixpoint; the rules start from their recursive delta and probe it by receiverGate: every output relation BYTE-identical old vs new, same facts, on both a 1,266-file and a 4,461-file subject. Serial solve 13.3s → 9.4s (−29%) small, 192s → 99s user (−48%) large.
tests/run.py --lang typescript: 237/262, the same 25 const-object checks that fail on the base.Also:
run-souffle.shlearnsAXIOM_DL_PROFILE=<file>(interpreter solve with per-rule profiling) — how these were found, kept for the next language.Round 2 is profiling now (next tier:
holder_holds_function6s,elem_read_fn3s, the zero-tupleqname_walkseed); will push further commits to this branch.