Skip to content

fixes #25687; optimizes seq assignment for orc#25689

Open
ringabout wants to merge 6 commits intodevelfrom
pr_gogo
Open

fixes #25687; optimizes seq assignment for orc#25689
ringabout wants to merge 6 commits intodevelfrom
pr_gogo

Conversation

@ringabout
Copy link
Copy Markdown
Member

@ringabout ringabout commented Apr 1, 2026

fixes #25687

This pull request introduces an optimization for sequence (seq) assignments and copies in the Nim compiler, enabling bulk memory copying for sequences whose element types are trivially copyable (i.e., no GC references or destructors). This can significantly improve performance for such types by avoiding per-element loops.

Key changes:

Compiler code generation improvements

  • Added the elemSupportsCopyMem function in compiler/liftdestructors.nim to detect if a sequence's element type is trivially copyable (no GC refs, no destructors).
  • Updated the fillSeqOp procedure to use a new genBulkCopySeq code path for eligible element types, generating a call to nimCopySeqPayload for efficient bulk copying. Fallback to the element-wise loop remains for non-trivial types. [1] [2]

Runtime support

  • Introduced the nimCopySeqPayload procedure in lib/system/seqs_v2.nim, which performs the actual bulk memory copy of sequence data using copyMem. This is only used for types that are safe for such an operation.

These changes collectively improve the efficiency of sequence operations for simple types, while maintaining correctness for complex types.

Benchmarked the original micro-benchmark:

refc: 3.52s user 0.02s system 99% cpu 3.538 total
orc (after change): 3.46s user 0.01s system 99% cpu 3.476 total

Copilot AI review requested due to automatic review settings April 1, 2026 11:00

This comment was marked as outdated.

ringabout and others added 3 commits April 1, 2026 19:09
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@ringabout
Copy link
Copy Markdown
Member Author

@codex review

chatgpt-codex-connector[bot]

This comment was marked as outdated.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 4 out of 4 changed files in this pull request and generated 1 comment.


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

Comment on lines 643 to +665
@@ -633,9 +656,13 @@ proc fillSeqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
# var i = 0
# while i < y.len: dest[i] = y[i]; inc(i)
# This is usually more efficient than a destroy/create pair.
# For trivially copyable types, use bulk copyMem instead of element loop.
checkSelfAssignment(c, t, body, x, y)
body.add setLenSeqCall(c, t, x, y)
forallElements(c, t, body, x, y)
if supportsCopyMem(t.elementType):
genBulkCopySeq(c, t, body, x, y)
else:
forallElements(c, t, body, x, y)
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

New bulk-copy path for seq assignment/copy is performance-critical and changes generated code for ORC/ARC. Please add a regression test that asserts this path is exercised for a trivially-copyable element type (e.g., seq[byte]), ideally by checking --expandArc/--expandOrc (or other compiler output) contains a call to nimCopySeqPayload, so the optimization doesn’t silently regress again.

Copilot uses AI. Check for mistakes.
cond.typ = getSysType(c.g, c.info, tyBool)
body.add genIf(c, cond, newTreeI(nkReturnStmt, c.info, newNodeI(nkEmpty, c.info)))

proc genBulkCopySeq(c: var TLiftCtx; t: PType; body, x, y: PNode) =
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.

why generate this in the compiler? can't it be library code?

Copy link
Copy Markdown
Member

@Araq Araq Apr 1, 2026

Choose a reason for hiding this comment

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

The =copy hook for seq is still special magic in Nim 2. Mostly caused by the fact that people expect seq to work within Nim's VM which doesn't support the required cast/alloc/etc stuff. There is also const s = @["abc"] which is valid Nim code (makes no sense here but comes up for Table in const sections).

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

orc: seq assignment slow

4 participants