Skip to content

BE-614: HashQL: Generate synthetic closure bodies for intrinsics used as first-class values#8895

Open
indietyp wants to merge 3 commits into
bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closurefrom
bm/be-614-hashql-generate-synthetic-mir-bodies-for-intrinsics-in-value
Open

BE-614: HashQL: Generate synthetic closure bodies for intrinsics used as first-class values#8895
indietyp wants to merge 3 commits into
bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closurefrom
bm/be-614-hashql-generate-synthetic-mir-bodies-for-intrinsics-in-value

Conversation

@indietyp

Copy link
Copy Markdown
Member

🌟 What is the purpose of this PR?

Allows intrinsics to be used in value position (passed as arguments, bound to variables) by generating synthetic MIR wrapper bodies during reification. Previously, intrinsics like <= could only appear at call sites where specialization rewrites them. Now they can flow through higher-order functions:

let apply = fn (a, b, f) = (f a b) in
(apply 2 3 <=)

🔍 What does this change?

Synthetic body generation:

  • Synthetics struct in CrossCompileState manages creation and caching of wrapper bodies
  • SyntheticBuilder generates MIR bodies with fat closure ABI (unit env as first parameter)
  • T! macro for matching qualified paths against ConstantSymbol arrays: &T![::core::cmp::gt] in slice patterns, sym::path::core::cmp::gt::CONST for the name
  • Dispatch table covers all first-classable intrinsics (comparison, boolean, arithmetic, bitwise) with local binary!/unary! macros deriving path and name from the same segments

Thin-call specialization:

  • rvalue_call_thin_specialize recognizes Call(Thin, Qualified(intrinsic), []) (the administrative thunk-force from the thunking phase) and produces the closure aggregate directly, skipping thunk body generation
  • Type unwrapping handles the thunking phase's () -> ClosureType wrapper to extract the actual signature

Intrinsic classification:

  • First-classable: comparison (gt, lt, gte, lte, eq, ne), boolean (and, or, not), arithmetic (add, sub), bitwise (and, or, not)
  • Unconstructible MIR ops (BinOp variants with ! payload): mul, div, rem, mod, pow, xor, shl, shr
  • No MIR ops: sqrt, cbrt, root
  • Not first-classable (syntactic forms): graph::head::entities, graph::body::filter, graph::tail::collect produce a specific user-facing diagnostic

Diagnostics:

  • intrinsic_not_first_class: user-facing error for graph intrinsics in value position
  • synthetic_binary_arity_mismatch / synthetic_unary_arity_mismatch: ICE for monomorphized type invariant violations

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • does not modify any publishable blocks or libraries, or modifications do not need publishing

📜 Does this require a change to the docs?

The changes in this PR:

  • are internal and do not require a docs change

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • do not affect the execution graph

⚠️ Known issues

  • Bare intrinsic at module root ("<=" as the entire program) is not supported. The thunking phase does not wrap the root body when it is a variable, so it never reaches the synthetic machinery. Tracked with a run: skip test.

🐾 Next steps

  • Untyped property access (the original motivation for this work)
  • Module system support for root-level qualified paths (BE-67)

🛡 What tests cover this?

Compiletests (8 new):

  • reify/synthetic-intrinsic-value: basic synthetic body generation and thin-call specialization
  • reify/synthetic-intrinsic-reused: same intrinsic used twice shares one body (caching)
  • reify/synthetic-intrinsic-multiple: different intrinsics get separate bodies
  • reify/synthetic-graph-not-first-class: graph intrinsic in value position produces error
  • reify/synthetic-intrinsic-bare: bare intrinsic at root (run: skip)
  • interpret/synthetic-intrinsic-value: end-to-end correctness (evaluates to true)
  • post_inline/synthetic-intrinsic-hof: full optimization cascade with constants (collapses to return true)
  • post_inline/synthetic-intrinsic-hof-dynamic: HOF with dynamic inputs collapses to bare x <= y

❓ How to test this?

cargo run --package hashql-compiletest -- run --filter "test(synthetic)"

📹 Demo

The post_inline/synthetic-intrinsic-hof-dynamic test shows the full cascade. A higher-order function receiving <= as a value with dynamic inputs:

Initial:  construct closure for <=, pass to apply, call through fat pointer
Final:    %0 = input LOAD x
          %1 = input LOAD y
          %2 = %0 <= %1
          return %2

All indirection eliminated. Indistinguishable from writing ["<=", x, y] directly.

Copilot AI review requested due to automatic review settings June 22, 2026 16:43
@vercel

vercel Bot commented Jun 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hash Ready Ready Preview, Comment Jun 23, 2026 10:16am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
hashdotdesign-tokens Ignored Ignored Preview Jun 23, 2026 10:16am
petrinaut Skipped Skipped Jun 23, 2026 10:16am

@vercel vercel Bot temporarily deployed to Preview – petrinaut June 22, 2026 16:43 Inactive
@indietyp indietyp changed the title BE-614: HashQL MIR: Generate synthetic closure bodies for intrinsics used as first-class values BE-614: HashQL: Generate synthetic closure bodies for intrinsics used as first-class values Jun 22, 2026
@cursor

cursor Bot commented Jun 22, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches MIR reification and codegen for all qualified intrinsics in value position; wrong dispatch or ABI could miscompile HOF code, though behavior is heavily covered by new compiletests.

Overview
Enables intrinsics in value position (e.g. passing <= into a higher-order function) by generating cached synthetic MIR bodies during reification, instead of treating qualified paths as unsupported external modules.

Reification adds a Synthetics cache on cross-compile state. Qualified paths matching known ::core::cmp, ::core::bool, ::core::math, and ::core::bits intrinsics become fat-closure bodies (Source::Synthetic) with optional thunk wrappers; graph forms like ::graph::head::entities get intrinsic_not_first_class instead of a generic module error. Thin-call specialization (rvalue_call_thin_specialize) beta-reduces Call(Thin, Qualified(intrinsic), []) straight to a closure aggregate when the thunking phase forced a zero-arg call.

Supporting tweaks: ConstantSymbolSymbol conversion, lhs/rhs symbols for synthetic locals, scratch.reset() after MIR reify in graph compile, and compiletests for reuse, multiple intrinsics, HOF + inlining, and graph-not-first-class.

Reviewed by Cursor Bugbot for commit 5f1207d. Bugbot is set up for automated code reviews on this repo. Configure here.

Copy link
Copy Markdown
Member Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 48906c1. Configure here.

Comment thread libs/@local/hashql/mir/src/reify/synthetic.rs
@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 31.82%. Comparing base (d051ddb) to head (5f1207d).

Files with missing lines Patch % Lines
libs/@local/graph/api/src/rest/hashql/compile.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@                                          Coverage Diff                                          @@
##           bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closure    #8895      +/-   ##
=====================================================================================================
+ Coverage                                                              26.83%   31.82%   +4.99%     
=====================================================================================================
  Files                                                                    652      683      +31     
  Lines                                                                  50479    54881    +4402     
  Branches                                                                3324     3439     +115     
=====================================================================================================
+ Hits                                                                   13547    17468    +3921     
- Misses                                                                 36777    37211     +434     
- Partials                                                                 155      202      +47     
Flag Coverage Δ
apps.hash-ai-worker-ts 1.39% <ø> (ø)
apps.hash-api 0.00% <ø> (ø)
local.hash-backend-utils 2.82% <ø> (ø)
local.hash-graph-sdk 9.63% <ø> (ø)
local.hash-isomorphic-utils 0.00% <ø> (ø)
rust.hash-graph-api 7.63% <0.00%> (-0.01%) ⬇️
rust.hashql-compiletest 28.39% <ø> (ø)
rust.hashql-eval 82.10% <ø> (ø)
rust.hashql-hir 89.09% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codspeed-hq

codspeed-hq Bot commented Jun 22, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 32.76%

⚡ 1 improved benchmark
❌ 2 regressed benchmarks
✅ 77 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
runtime 29.7 ns 58.9 ns -49.53%
constant 29.7 ns 58.9 ns -49.53%
pattern_match_constant 180 ns 150.8 ns +19.34%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing bm/be-614-hashql-generate-synthetic-mir-bodies-for-intrinsics-in-value (5f1207d) with bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closure (d051ddb)

Open in CodSpeed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the HashQL MIR reification pipeline to allow certain intrinsics (e.g. <=) to be used as first-class values (passed/bound like normal functions) by generating cached synthetic MIR wrapper bodies, and adds a thin-call specialization to avoid generating intermediary thunk bodies when forcing qualified intrinsics. It also adds diagnostics for intrinsics that are syntactic-only (graph intrinsics) when used in value position, and introduces compiletests covering the new behavior and optimization outcomes.

Changes:

  • Add synthetic MIR body/thunk generation + caching for a set of “first-classable” intrinsics during reification.
  • Specialize thin calls of qualified intrinsics (Call(Thin, Qualified(...), [])) into direct closure aggregates.
  • Add diagnostics + extensive UI tests; reset scratch allocators after reify to avoid retaining transient allocations.

Reviewed changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
libs/@local/hashql/mir/src/reify/synthetic.rs New synthetic body/thunk generation & intrinsic dispatch.
libs/@local/hashql/mir/src/reify/rvalue.rs Thin-call specialization to produce closure aggregates directly for intrinsics.
libs/@local/hashql/mir/src/reify/mod.rs Wire Synthetics into CrossCompileState.
libs/@local/hashql/mir/src/reify/error.rs Add diagnostics for synthetic arity mismatches and non-first-class intrinsics.
libs/@local/hashql/mir/src/reify/atom.rs Route qualified variables through synthetic thunk generation when applicable; avoid duplicate diagnostics.
libs/@local/hashql/mir/src/lib.rs Enable stmt_expr_attributes for in-function attributes used in the synthetic matcher.
libs/@local/hashql/core/src/symbol/sym.rs Add lhs/rhs symbols for synthetic local naming.
libs/@local/hashql/core/src/symbol/mod.rs Add From<ConstantSymbol> for Symbol to simplify diagnostics plumbing.
libs/@local/hashql/compiletest/src/pipeline.rs Reset scratch allocator after MIR reification.
libs/@local/graph/api/src/rest/hashql/compile.rs Reset scratch allocator after MIR reification (and later phases).
libs/@local/hashql/mir/tests/ui/reify/synthetic-intrinsic-value.jsonc New UI test: intrinsic value position triggers synthetic wrapper.
libs/@local/hashql/mir/tests/ui/reify/synthetic-intrinsic-value.stdout Expected MIR output for the above.
libs/@local/hashql/mir/tests/ui/reify/synthetic-intrinsic-reused.jsonc New UI test: synthetic body caching (reuse).
libs/@local/hashql/mir/tests/ui/reify/synthetic-intrinsic-reused.stdout Expected MIR output for the above.
libs/@local/hashql/mir/tests/ui/reify/synthetic-intrinsic-multiple.jsonc New UI test: multiple intrinsics generate distinct synthetic bodies.
libs/@local/hashql/mir/tests/ui/reify/synthetic-intrinsic-multiple.stdout Expected MIR output for the above.
libs/@local/hashql/mir/tests/ui/reify/synthetic-intrinsic-bare.jsonc New skipped UI test documenting root-level bare intrinsic limitation.
libs/@local/hashql/mir/tests/ui/reify/synthetic-graph-not-first-class.jsonc New UI test: graph intrinsic rejected in value position.
libs/@local/hashql/mir/tests/ui/reify/synthetic-graph-not-first-class.stderr Expected diagnostic output for the above.
libs/@local/hashql/mir/tests/ui/pass/post_inline/synthetic-intrinsic-hof.jsonc New pass test: HOF + intrinsic value optimizes to constant.
libs/@local/hashql/mir/tests/ui/pass/post_inline/synthetic-intrinsic-hof.stdout Expected MIR pipeline output for the above.
libs/@local/hashql/mir/tests/ui/pass/post_inline/synthetic-intrinsic-hof-dynamic.jsonc New pass test: dynamic HOF retains comparison shape post-inline.
libs/@local/hashql/mir/tests/ui/pass/post_inline/synthetic-intrinsic-hof-dynamic.stdout Expected MIR pipeline output for the above.
libs/@local/hashql/mir/tests/ui/interpret/synthetic-intrinsic-value.jsonc New interpret test: end-to-end evaluation correctness.
libs/@local/hashql/mir/tests/ui/interpret/synthetic-intrinsic-value.stdout Expected interpreter output for the above.
libs/@local/hashql/mir/tests/ui/interpret/synthetic-intrinsic-value.aux.mir Expected MIR pipeline output for interpret case.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread libs/@local/hashql/mir/src/reify/synthetic.rs
Comment thread libs/@local/hashql/mir/src/reify/synthetic.rs
Comment thread libs/@local/hashql/mir/src/reify/synthetic.rs Outdated
@indietyp indietyp force-pushed the bm/be-614-hashql-generate-synthetic-mir-bodies-for-intrinsics-in-value branch from 48906c1 to c5a86df Compare June 23, 2026 09:41
@indietyp indietyp force-pushed the bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closure branch from 8efe84c to a0c8ad1 Compare June 23, 2026 09:41
@vercel vercel Bot temporarily deployed to Preview – petrinaut June 23, 2026 09:41 Inactive
@indietyp indietyp force-pushed the bm/be-614-hashql-generate-synthetic-mir-bodies-for-intrinsics-in-value branch from c5a86df to feac27a Compare June 23, 2026 09:52
@indietyp indietyp force-pushed the bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closure branch from a0c8ad1 to 0ddf199 Compare June 23, 2026 09:52
@vercel vercel Bot temporarily deployed to Preview – petrinaut June 23, 2026 09:52 Inactive
Copilot AI review requested due to automatic review settings June 23, 2026 10:02
@indietyp indietyp force-pushed the bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closure branch from 0ddf199 to d051ddb Compare June 23, 2026 10:02
@indietyp indietyp force-pushed the bm/be-614-hashql-generate-synthetic-mir-bodies-for-intrinsics-in-value branch from feac27a to 5f1207d Compare June 23, 2026 10:02
@vercel vercel Bot temporarily deployed to Preview – petrinaut June 23, 2026 10:03 Inactive

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated 3 comments.

Comment thread libs/@local/hashql/mir/src/reify/synthetic.rs
Comment thread libs/@local/hashql/mir/src/reify/synthetic.rs
Comment thread libs/@local/hashql/mir/src/reify/atom.rs
@github-actions

Copy link
Copy Markdown
Contributor

Benchmark results

@rust/hash-graph-benches – Integrations

policy_resolution_large

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2002 $$26.7 \mathrm{ms} \pm 174 \mathrm{μs}\left({\color{gray}1.88 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.41 \mathrm{ms} \pm 17.7 \mathrm{μs}\left({\color{gray}-3.213 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1001 $$12.7 \mathrm{ms} \pm 100 \mathrm{μs}\left({\color{gray}0.770 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 3314 $$44.2 \mathrm{ms} \pm 383 \mathrm{μs}\left({\color{gray}1.66 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$15.0 \mathrm{ms} \pm 114 \mathrm{μs}\left({\color{gray}-1.675 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 1526 $$24.3 \mathrm{ms} \pm 171 \mathrm{μs}\left({\color{gray}-0.931 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 2078 $$27.9 \mathrm{ms} \pm 142 \mathrm{μs}\left({\color{gray}3.96 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.97 \mathrm{ms} \pm 60.1 \mathrm{μs}\left({\color{gray}2.47 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 1033 $$14.0 \mathrm{ms} \pm 87.7 \mathrm{μs}\left({\color{red}5.06 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_medium

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 102 $$3.73 \mathrm{ms} \pm 23.5 \mathrm{μs}\left({\color{gray}0.336 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.03 \mathrm{ms} \pm 16.0 \mathrm{μs}\left({\color{lightgreen}-12.233 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 51 $$3.35 \mathrm{ms} \pm 14.9 \mathrm{μs}\left({\color{gray}-3.334 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 269 $$5.21 \mathrm{ms} \pm 50.3 \mathrm{μs}\left({\color{gray}0.634 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$3.59 \mathrm{ms} \pm 17.3 \mathrm{μs}\left({\color{gray}-1.337 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 107 $$4.16 \mathrm{ms} \pm 31.4 \mathrm{μs}\left({\color{gray}0.974 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 133 $$4.37 \mathrm{ms} \pm 28.0 \mathrm{μs}\left({\color{gray}-0.558 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.50 \mathrm{ms} \pm 17.3 \mathrm{μs}\left({\color{gray}1.33 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 63 $$4.09 \mathrm{ms} \pm 31.2 \mathrm{μs}\left({\color{gray}1.34 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_none

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2 $$2.72 \mathrm{ms} \pm 13.4 \mathrm{μs}\left({\color{gray}3.05 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.54 \mathrm{ms} \pm 15.3 \mathrm{μs}\left({\color{gray}1.50 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1 $$2.69 \mathrm{ms} \pm 16.4 \mathrm{μs}\left({\color{gray}4.16 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 8 $$2.97 \mathrm{ms} \pm 14.6 \mathrm{μs}\left({\color{gray}2.06 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.78 \mathrm{ms} \pm 16.3 \mathrm{μs}\left({\color{gray}4.49 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 3 $$2.96 \mathrm{ms} \pm 18.1 \mathrm{μs}\left({\color{gray}3.56 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_small

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 52 $$3.03 \mathrm{ms} \pm 19.1 \mathrm{μs}\left({\color{gray}1.26 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.77 \mathrm{ms} \pm 18.6 \mathrm{μs}\left({\color{gray}0.026 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 25 $$2.96 \mathrm{ms} \pm 13.2 \mathrm{μs}\left({\color{gray}-0.949 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 94 $$3.39 \mathrm{ms} \pm 20.4 \mathrm{μs}\left({\color{gray}-1.993 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$2.94 \mathrm{ms} \pm 12.4 \mathrm{μs}\left({\color{gray}-0.704 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 26 $$3.26 \mathrm{ms} \pm 14.2 \mathrm{μs}\left({\color{gray}-0.252 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 66 $$3.33 \mathrm{ms} \pm 18.0 \mathrm{μs}\left({\color{gray}0.506 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.99 \mathrm{ms} \pm 16.9 \mathrm{μs}\left({\color{gray}1.48 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 29 $$3.35 \mathrm{ms} \pm 26.9 \mathrm{μs}\left({\color{gray}0.723 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_complete

Function Value Mean Flame graphs
entity_by_id;one_depth 1 entities $$42.8 \mathrm{ms} \pm 204 \mathrm{μs}\left({\color{gray}3.20 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 10 entities $$33.4 \mathrm{ms} \pm 203 \mathrm{μs}\left({\color{lightgreen}-15.538 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 25 entities $$36.3 \mathrm{ms} \pm 170 \mathrm{μs}\left({\color{lightgreen}-13.426 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 5 entities $$32.1 \mathrm{ms} \pm 180 \mathrm{μs}\left({\color{lightgreen}-13.664 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 50 entities $$42.7 \mathrm{ms} \pm 226 \mathrm{μs}\left({\color{lightgreen}-22.029 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 1 entities $$50.0 \mathrm{ms} \pm 312 \mathrm{μs}\left({\color{lightgreen}-18.260 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 10 entities $$41.2 \mathrm{ms} \pm 261 \mathrm{μs}\left({\color{lightgreen}-22.645 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 25 entities $$93.4 \mathrm{ms} \pm 408 \mathrm{μs}\left({\color{lightgreen}-12.795 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 5 entities $$35.0 \mathrm{ms} \pm 233 \mathrm{μs}\left({\color{lightgreen}-37.989 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 50 entities $$276 \mathrm{ms} \pm 933 \mathrm{μs}\left({\color{lightgreen}-8.745 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 1 entities $$10.5 \mathrm{ms} \pm 56.8 \mathrm{μs}\left({\color{lightgreen}-23.522 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 10 entities $$10.6 \mathrm{ms} \pm 65.7 \mathrm{μs}\left({\color{lightgreen}-20.076 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 25 entities $$10.7 \mathrm{ms} \pm 66.0 \mathrm{μs}\left({\color{lightgreen}-21.553 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 5 entities $$10.4 \mathrm{ms} \pm 80.4 \mathrm{μs}\left({\color{lightgreen}-23.806 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 50 entities $$10.7 \mathrm{ms} \pm 61.5 \mathrm{μs}\left({\color{lightgreen}-25.985 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_linkless

Function Value Mean Flame graphs
entity_by_id 1 entities $$10.5 \mathrm{ms} \pm 73.6 \mathrm{μs}\left({\color{lightgreen}-24.301 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10 entities $$10.7 \mathrm{ms} \pm 50.2 \mathrm{μs}\left({\color{lightgreen}-21.928 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 100 entities $$10.9 \mathrm{ms} \pm 66.7 \mathrm{μs}\left({\color{lightgreen}-22.613 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 1000 entities $$11.1 \mathrm{ms} \pm 69.5 \mathrm{μs}\left({\color{lightgreen}-20.782 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10000 entities $$10.9 \mathrm{ms} \pm 70.0 \mathrm{μs}\left({\color{lightgreen}-25.492 \mathrm{\%}}\right) $$ Flame Graph

representative_read_entity

Function Value Mean Flame graphs
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/block/v/1 $$11.0 \mathrm{ms} \pm 101 \mathrm{μs}\left({\color{lightgreen}-23.437 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/book/v/1 $$11.1 \mathrm{ms} \pm 69.7 \mathrm{μs}\left({\color{lightgreen}-22.183 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/building/v/1 $$11.0 \mathrm{ms} \pm 57.4 \mathrm{μs}\left({\color{lightgreen}-14.912 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/organization/v/1 $$11.3 \mathrm{ms} \pm 75.1 \mathrm{μs}\left({\color{lightgreen}-20.391 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/page/v/2 $$10.9 \mathrm{ms} \pm 63.8 \mathrm{μs}\left({\color{lightgreen}-17.833 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/person/v/1 $$11.0 \mathrm{ms} \pm 56.2 \mathrm{μs}\left({\color{lightgreen}-22.408 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/playlist/v/1 $$11.3 \mathrm{ms} \pm 58.7 \mathrm{μs}\left({\color{lightgreen}-18.877 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/song/v/1 $$11.0 \mathrm{ms} \pm 71.3 \mathrm{μs}\left({\color{lightgreen}-22.823 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/uk-address/v/1 $$11.2 \mathrm{ms} \pm 75.0 \mathrm{μs}\left({\color{lightgreen}-16.767 \mathrm{\%}}\right) $$ Flame Graph

representative_read_entity_type

Function Value Mean Flame graphs
get_entity_type_by_id Account ID: bf5a9ef5-dc3b-43cf-a291-6210c0321eba $$8.63 \mathrm{ms} \pm 50.6 \mathrm{μs}\left({\color{lightgreen}-16.663 \mathrm{\%}}\right) $$ Flame Graph

representative_read_multiple_entities

Function Value Mean Flame graphs
entity_by_property traversal_paths=0 0 $$60.5 \mathrm{ms} \pm 393 \mathrm{μs}\left({\color{lightgreen}-10.956 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$109 \mathrm{ms} \pm 532 \mathrm{μs}\left({\color{lightgreen}-15.839 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$68.6 \mathrm{ms} \pm 926 \mathrm{μs}\left({\color{lightgreen}-8.120 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$77.9 \mathrm{ms} \pm 608 \mathrm{μs}\left({\color{lightgreen}-8.637 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$82.5 \mathrm{ms} \pm 563 \mathrm{μs}\left({\color{lightgreen}-13.460 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true $$88.9 \mathrm{ms} \pm 547 \mathrm{μs}\left({\color{lightgreen}-13.593 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=0 0 $$45.0 \mathrm{ms} \pm 282 \mathrm{μs}\left({\color{lightgreen}-11.268 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$74.3 \mathrm{ms} \pm 389 \mathrm{μs}\left({\color{lightgreen}-11.610 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$52.0 \mathrm{ms} \pm 425 \mathrm{μs}\left({\color{lightgreen}-9.563 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$62.5 \mathrm{ms} \pm 338 \mathrm{μs}\left({\color{lightgreen}-10.507 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$63.8 \mathrm{ms} \pm 302 \mathrm{μs}\left({\color{lightgreen}-11.557 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true $$64.1 \mathrm{ms} \pm 275 \mathrm{μs}\left({\color{lightgreen}-10.835 \mathrm{\%}}\right) $$

scenarios

Function Value Mean Flame graphs
full_test query-limited $$125 \mathrm{ms} \pm 595 \mathrm{μs}\left({\color{gray}-4.932 \mathrm{\%}}\right) $$ Flame Graph
full_test query-unlimited $$136 \mathrm{ms} \pm 449 \mathrm{μs}\left({\color{gray}-3.805 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-limited $$23.6 \mathrm{ms} \pm 120 \mathrm{μs}\left({\color{red}29.6 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-unlimited $$529 \mathrm{ms} \pm 894 \mathrm{μs}\left({\color{gray}-2.114 \mathrm{\%}}\right) $$ Flame Graph

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/libs Relates to first-party libraries/crates/packages (area) area/tests New or updated tests type/eng > backend Owned by the @backend team

Development

Successfully merging this pull request may close these issues.

2 participants