Skip to content

npm: marked workload (mdapp.ts) is superlinear — 10 docs 0.16s, 100 docs >5min, 300 docs >55min (node: ~1s for 300) #7692

Closed

Description

@proggeramlug

Summary

With #7689 fixed (PR #7691), the marked npm package now runs correctly under Perry — but the issue's full comparison workload cannot be run to completion because Perry's runtime scales severely superlinearly in the number of documents parsed.

gc-handoff/apps/mdapp/mdapp.ts (300 generated markdown docs through marked.parse, counting <h2> tags):

docs node perry (perry-dev profile @ 94ad784 + #7691 fix)
10 ~0.1 s, 20105 60 0.16 s, 20105 60 (matches)
100 ~0.4 s killed at 5 min, not finished
300 ~1 s, 612040 1800 killed at ~55 min, not finished

10 → 100 docs is a >1800× wall-clock blowup for 10× the input. Per-doc input size is essentially constant, so something in the per-parse path is superlinear in cumulative work — a side table growing per allocation/registration with O(total) lookups, GC behavior, or similar. The process stays ~50% CPU-busy the whole time (computing, not blocked).

Caveats on the numbers: measured on a loaded dev machine with an opt-level=1 (perry-dev) runtime, so the absolute times overstate the constant factor — but not the growth curve. Worth re-measuring --release on the quiet bench host first to get a clean curve before digging.

Repro

cd gc-handoff/apps/mdapp
export PERRY_RUNTIME_DIR=<repo>/target/release
<repo>/target/release/perry mdapp.ts -o p_mdapp
time ./p_mdapp        # does not finish in any reasonable time
# vs: edit the loop to `i < 10` — finishes instantly with output matching node

Context

This is the axis of the scriptc comparison in #7689: scriptc --dynamic produces 612040 1800 through its embedded engine in seconds; Perry now computes correct results natively but cannot finish the workload. Correctness landed in #7691; this issue tracks the scaling defect.

Activity

  1. proggeramlug commented on Aug 10, 2026

    @proggeramlug
    ContributorAuthor

    Re-measured on main @ db44b31b7, as this issue asks (--release on a clean build, plus the perry-dev arm the original numbers came from). The superlinearity is gone in both profiles, and the full 300-document workload now completes with output identical to node.

    docs node v26.5.1 perry --release perry perry-dev this issue reported (94ad78435 + #7691, perry-dev)
    10 — 0.09 s — 0.16 s
    40 — 0.17 s — —
    100 — 0.36 s 1.17 s killed at 5 min, unfinished
    300 0.43 s 1.08 s 2.83 s killed at ~55 min, unfinished

    Output at 300 docs is 612040 1800 from --release, from perry-dev, and from node --experimental-strip-types — the exact value this issue names as node's. At 100 docs perry-dev prints 202640 600, consistent with the same per-doc rate.

    The curve is now linear, not superlinear: --release runs 0.09 / 0.17 / 0.36 s at 10 / 40 / 100 docs, i.e. ~3.6 ms per document flat, and 300 docs lands where extrapolation puts it. The >1800× blowup between 10 and 100 documents does not reproduce.

    Notes on method, since this issue was explicit about them:

    • Timings are best-of-repeats after a warm run — the first execution of each binary was consistently slower (n=100 measured 1.37 s cold against 0.36 s warm, n=300 1.82 s cold against 1.08 s), which is enough to make a single cold sample look like a curve. My own first pass at 10/20/40 came out non-monotonic for that reason before I re-ran it.
    • PERRY_NO_AUTO_OPTIMIZE=1, PERRY_RUNTIME_DIR pinned at freshly built archives, mtimes verified. The perry-dev arm was rebuilt immediately before measuring because an unrelated A/B earlier in the session had left those archives built from a modified constant — worth stating, because that is exactly the stale-archive trap that makes an A/B vacuous.

    This was not fixed by anything targeted at it. 78+ commits separate 94ad78435 from current main, a dozen of them in the collector — #7742's whole-block in-place promotion, #7733's yield-adaptive major pacing, #7690/#7721 restoring evacuation at precise safepoints — and the symptom described here (~50% CPU-busy, cost growing with cumulative rather than per-document work) is the shape those changes address.

    Perry is now 2.5× node on this workload at 300 documents rather than unable to finish it. Closing as no longer reproducing; the remaining constant-factor gap belongs to the ordinary benchmark ladder, not to a scaling defect.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugConfirmed defect or regression

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions