원클릭으로
profile
Profile Arizona hot paths with eprof/fprof. Use when investigating performance or picking the next optimization.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Profile Arizona hot paths with eprof/fprof. Use when investigating performance or picking the next optimization.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Add a new route to the Arizona router configuration. Use when creating new pages or endpoints.
Scaffold a new Arizona handler module. Ask whether it's a route-level view or an embeddable stateful component.
Trace an event through the full Arizona stack from client click to DOM patch. Use when debugging event handling.
Add tests for an Arizona module. Use when creating CT suites, inline EUnit tests, or E2E tests.
Format, check, test, and commit changes. Use before committing any code changes.
Debug Arizona stream operations. Use when investigating stream insert/delete/update/move/sort/reset behavior.
| name | profile |
| description | Profile Arizona hot paths with eprof/fprof. Use when investigating performance or picking the next optimization. |
| argument-hint | ["workload_label"] |
| allowed-tools | Read, Bash, Grep, Glob |
Profile an Arizona workload to find hot paths and propose the next
optimization. If $ARGUMENTS is empty, profile the full curated set
(render_view_page, render_each_100, diff_simple_event,
stream_reorder_100).
Pick --ops based on the workload's per-op cost so total profile time
is in the 20–100ms range (enough signal, not so much that the analysis
itself dominates):
| Workload | Suggested --ops |
|---|---|
render_view_page | 1000 |
render_view_page_dyn_js | 200 |
render_each_100 | 200 |
render_nested_each | 200 |
render_stateful_chain | 1000 |
diff_simple_event | 5000 |
stream_reorder_100 | 200 |
stream_insert_1k | 50 |
http_get_e2e | 1000 |
ws_event_e2e | 1000 |
mount_only | 500 |
pubsub_broadcast_100 | 100 |
make prof ARGS="--only $ARGUMENTS --ops 1000 --min-ms 0.5"
The --min-ms 0.5 threshold filters out rows below 0.5ms total — keeps
the table readable. Drop to --min-ms 0.2 if the workload runs short.
Profile output also lands at /tmp/arizona_profile_<label>.log.
Group functions by what they're doing — that's how you pick a target:
binary:replace/4, binary:matches/3, binary:do_replace/4, binary:part/2 →
arizona_js:escape_attr/1 and friendsjson:escape_binary/5, json:string/7, json:do_encode/2, json:list_loop/2 →
arizona_socket:encode/1 reply path'-Fn/Arity-lc$^N/M-K-'/Arity or zlc$ →
per-item iteration overheadarizona_eval:eval_one/1, eval_val/1,
arizona_render:render_ssr_one/1, render_ssr_val/1arizona_render:zip/2, arizona_template:to_bin/1,
unwrap_val/1gen:do_call/4, erlang:demonitor/2,
erlang:integer_to_binary/1 — usually intrinsic, hard to optimizegen:do_call/4 ≥ 5% in event workloads
signals the live process call cost; usually not addressable without
re-architectingNote the totals row for before/after comparison (you'll re-run after changes to confirm the win).
Pick the highest-% row that's in Arizona code (not OTP). For each
candidate, find the call site and decide whether the cost is:
Quick lookup:
grep -rn 'function_name' src/ test/support/
Common accidental patterns:
Vals = f(Xs), [g(X, V) || X <- Xs && V <- Vals] →
fuse to [g(X, f_one(X)) || X <- Xs] (we did this for
render_ssr_val/1).escape(json_encode(Cmd))
where Cmd is a literal → fold at compile time in
arizona_parse_transform.erl (we did this for static arizona_js
commands).[{Az, V, #{}} || ...] where
the #{} deps map is never read → drop it.If the eprof flat profile isn't enough — e.g. a function shows 10% but you can't see what it's calling — rerun with fprof for OWN/ACC time and the call hierarchy:
make prof ARGS="--only $ARGUMENTS --tool fprof --ops 200"
fprof output is verbose. Read the totals block first, then sort by
OWN time and trace upwards from the heaviest leaf MFAs.
To compare a candidate change against a baseline without stashing the
working tree, profile any commit-ish via git worktree:
# Profile the parent commit (typical A/B baseline)
make prof-at REF=HEAD~1 ARGS="--only render_each_100 --ops 200"
# Profile a branch name, tag, or SHA -- all work
make prof-at REF=main ARGS="--only render_view_page --ops 1000"
make prof-at REF=9fe7497 ARGS="--only stream_insert_1k --ops 50"
The worktree is cached under _build/prof-at-<sha>/ (gitignored), so
repeat runs of the same commit reuse the compiled artifacts. Cleanup:
git worktree remove _build/prof-at-<sha> (or just git worktree prune
to remove all stale entries).
Before claiming a win, confirm the profile-suggested change hits the
wall clock too. Use make bench (real ns/op, multi-trial stats):
make bench ARGS="--only $ARGUMENTS 30"
The bench is intentionally NOT auto-gated (variance from shared CI runners). Compare mean ns/op before vs. after by hand.
State the hypothesis explicitly:
Function
M:F/Ais N% of<workload>total. The cost is accidental because . Replacing it with<edit>should drop it to ~M% and shave ~X% off the total.
Then propose one concrete edit. Per the user's preference, don't bundle multiple unrelated optimizations — ship one change, re-measure, then plan the next.
scripts/profile.escripttest/support/arizona_profiler.erlscripts/profile.escript profilers/0test/support/arizona_bench_lib.erlscripts/bench.escriptdocs/architecture.mdIf the hot path you want lives outside the four curated workloads:
bench_* workload from scripts/bench.escript
(typically the one named identically). The bench setup logic is the
right shape for profiling too.prof_<label>/2 function in scripts/profile.escript that
calls profile_loop/3 with the inner op fun.profilers/0.Keep the curated set small — this is for hot-path investigation, not exhaustive coverage.