Skip to content

Optimize unchanged FiberRefs updates#6453

Draft
coyaSONG wants to merge 1 commit into
Effect-TS:v3from
coyaSONG:agent/avoid-fiberref-noop-copy
Draft

Optimize unchanged FiberRefs updates#6453
coyaSONG wants to merge 1 commit into
Effect-TS:v3from
coyaSONG:agent/avoid-fiberref-noop-copy

Conversation

@coyaSONG

@coyaSONG coyaSONG commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Type

  • Refactor
  • Feature
  • Bug Fix
  • Optimization
  • Documentation Update

Description

FiberRefs.updateAs cloned the complete locals map before unsafeUpdateAs could discover that the current fiber already held an equal value. Repeated unchanged FiberRef updates therefore remained O(R) in the number of unrelated refs.

This change computes the replacement stack first and returns the original FiberRefs when the same fiber's value is unchanged. Updates from a different fiber still append a history entry, and changed values still copy the map to preserve immutable snapshots.

A local 7-sample median microbenchmark with 500 populated refs and 20,000 unchanged updates measured the map-cloning baseline at 476.9 ms and the optimized path at 0.69 ms (about 691x faster).

Implementation and validation were assisted by OpenAI Codex. No independent human review is claimed.

Validation:

  • corepack pnpm lint-fix
  • corepack pnpm vitest packages/effect/test/FiberRefs.test.ts packages/effect/test/FiberRef.test.ts --run (40 tests)
  • corepack pnpm check
  • corepack pnpm build
  • corepack pnpm docgen
  • git diff --check

Related

Summary by CodeRabbit

  • Performance

    • Improved FiberRefs updates to avoid unnecessary copying when a value remains unchanged.
  • Bug Fixes

    • Preserved existing FiberRefs instances for no-op updates while correctly creating updated instances when changes affect another fiber.
  • Tests

    • Added coverage for instance reuse and child-fiber update behavior.

@github-project-automation github-project-automation Bot moved this to Discussion Ongoing in PR Backlog Jul 17, 2026
@changeset-bot

changeset-bot Bot commented Jul 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: bd05883

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
effect Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@IMax153 IMax153 added the 3.0 Used for issues, pull requests, etc. that are relevant for the `v3` branch targeting Effect v3. label Jul 17, 2026
@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

FiberRefs update logic now centralizes stack computation, reuses the original instance when values are unchanged, and preserves distinct entries for child fibers. Tests cover identity behavior and a patch Changesets entry documents the change.

Changes

FiberRefs update reuse

Layer / File(s) Summary
Centralized stack computation
packages/effect/src/internal/fiberRefs.ts
The new updatedStack helper handles unchanged values, replacements, child-fiber entries, and missing entries.
Update integration and validation
packages/effect/src/internal/fiberRefs.ts, packages/effect/test/FiberRefs.test.ts, .changeset/fuzzy-spiders-smile.md
updateAs and unsafeUpdateAs use the shared stack logic; tests verify instance reuse and child updates, and the patch release note documents the behavior.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant updateAs
  participant updatedStack
  participant FiberRefsImpl
  Caller->>updateAs: request fiberRef update
  updateAs->>updatedStack: compute prospective stack
  alt value unchanged
    updatedStack-->>updateAs: undefined
    updateAs-->>Caller: original FiberRefs instance
  else stack changed
    updatedStack-->>updateAs: new stack
    updateAs->>FiberRefsImpl: create updated locals map
    FiberRefsImpl-->>updateAs: new FiberRefs instance
    updateAs-->>Caller: updated FiberRefs
  end
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main change: optimizing unchanged FiberRefs updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added the enhancement New feature or request label Jul 19, 2026

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/effect/test/FiberRefs.test.ts (1)

36-60: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the replacement branch and verify stack contents.

This test does not exercise same-fiber updates with a changed value, and checking only length === 2 does not prove that the child entry is first and the parent history is preserved. Add assertions for both stack entries and a changed-value update.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/effect/test/FiberRefs.test.ts` around lines 36 - 60, Extend the
“updateAs reuses unchanged FiberRefs for the same fiber” test to call
FiberRefs.updateAs with the original fiberId and a changed value, asserting the
returned structure is distinct and verifies the replacement branch. For the
childFiberRefs result, assert both stack entries’ fiberRef values and ordering:
the child’s value must be first, followed by the parent’s preserved history.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/effect/test/FiberRefs.test.ts`:
- Around line 51-59: Update the FiberRefs test checks around FiberRefs.updateAs
to import assert from `@effect/vitest` and replace the standalone strictEqual and
assertTrue helpers with assert.strictEqual and assert.notStrictEqual, preserving
the existing equality and identity assertions.

---

Nitpick comments:
In `@packages/effect/test/FiberRefs.test.ts`:
- Around line 36-60: Extend the “updateAs reuses unchanged FiberRefs for the
same fiber” test to call FiberRefs.updateAs with the original fiberId and a
changed value, asserting the returned structure is distinct and verifies the
replacement branch. For the childFiberRefs result, assert both stack entries’
fiberRef values and ordering: the child’s value must be first, followed by the
parent’s preserved history.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 40eae631-34f6-4675-9d46-4ef2e5f46e36

📥 Commits

Reviewing files that changed from the base of the PR and between 8a405fd and bd05883.

📒 Files selected for processing (3)
  • .changeset/fuzzy-spiders-smile.md
  • packages/effect/src/internal/fiberRefs.ts
  • packages/effect/test/FiberRefs.test.ts

Comment on lines +51 to +59
strictEqual(unchanged, fiberRefs)

const childFiberRefs = FiberRefs.updateAs(fiberRefs, {
fiberId: childId,
fiberRef,
value: 1
})
assertTrue(childFiberRefs !== fiberRefs)
strictEqual(childFiberRefs.locals.get(fiberRef)?.length, 2)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== FiberRefs.test.ts ==\n'
cat -n packages/effect/test/FiberRefs.test.ts | sed -n '1,220p'

printf '\n== Search assert imports/usages in package tests ==\n'
rg -n "from '`@effect/vitest`'|from \"`@effect/vitest`\"|assertTrue\\(|strictEqual\\(|assert\\." packages/effect/test packages/effect -g '*.ts' -g '*.tsx'

printf '\n== Nearby test files using `@effect/vitest` assert ==\n'
rg -n "from '`@effect/vitest`'|from \"`@effect/vitest`\"" packages/effect/test -g '*.ts' -g '*.tsx'

Repository: Effect-TS/effect

Length of output: 50373


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,120p' packages/effect/test/FiberRefs.test.ts | nl -ba

printf '\n--- assert-related imports in FiberRefs.test.ts ---\n'
rg -n "assert|strictEqual|assertTrue" packages/effect/test/FiberRefs.test.ts

printf '\n--- package-local test convention sample ---\n'
fd -a 'test.ts' packages/effect/test | head -n 10 | while read -r f; do
  echo "FILE: $f"
  rg -n "from '`@effect/vitest`'|from \"`@effect/vitest`\"|assert\\." "$f" || true
  echo
done

Repository: Effect-TS/effect

Length of output: 194


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '== FiberRefs.test.ts (top) ==\n'
sed -n '1,90p' packages/effect/test/FiberRefs.test.ts

printf '\n== FiberRefs.test.ts assertion/import lines ==\n'
grep -nE 'from "`@effect/vitest`"|from '\''`@effect/vitest`'\''|assertTrue\\(|strictEqual\\(|assert\\.' packages/effect/test/FiberRefs.test.ts || true

printf '\n== Nearby tests that import assert from `@effect/vitest` ==\n'
grep -R -nE 'from "`@effect/vitest`"|from '\''`@effect/vitest`'\''' packages/effect/test/FiberRefs.test.ts packages/effect/test/Fiber.test.ts packages/effect/test/FiberMap.test.ts packages/effect/test/PartitionedSemaphore.test.ts | head -n 80

Repository: Effect-TS/effect

Length of output: 3841


Use assert for these new checks. packages/effect/test/FiberRefs.test.ts:51-59 should import assert from @effect/vitest and use assert.strictEqual / assert.notStrictEqual here instead of the strictEqual / assertTrue helpers from @effect/vitest/utils.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/effect/test/FiberRefs.test.ts` around lines 51 - 59, Update the
FiberRefs test checks around FiberRefs.updateAs to import assert from
`@effect/vitest` and replace the standalone strictEqual and assertTrue helpers
with assert.strictEqual and assert.notStrictEqual, preserving the existing
equality and identity assertions.

Source: Coding guidelines

@github-project-automation github-project-automation Bot moved this from Discussion Ongoing to Waiting on Author in PR Backlog Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3.0 Used for issues, pull requests, etc. that are relevant for the `v3` branch targeting Effect v3. enhancement New feature or request

Projects

Status: Waiting on Author

Development

Successfully merging this pull request may close these issues.

2 participants