From 87cc6d0a9145481901aa8c0676765aff41598c19 Mon Sep 17 00:00:00 2001 From: Yuriy Glukhov Date: Wed, 10 Sep 2025 16:37:55 +0300 Subject: [PATCH] Optimize @, fixes #25063 (#25064) Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com> (cherry picked from commit 49e66e80f0656f5056c606d0f627b4163bdb22a1) --- lib/system.nim | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index f9986cda29..09f28677e7 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1449,6 +1449,8 @@ proc isNil*[T: proc | iterator {.closure.}](x: T): bool {.noSideEffect, magic: " ## Fast check whether `x` is nil. This is sometimes more efficient than ## `== nil`. +proc supportsCopyMem(t: typedesc): bool {.magic: "TypeTrait".} + when defined(nimHasTopDownInference): # magic used for seq type inference proc `@`*[T](a: openArray[T]): seq[T] {.magic: "OpenArrayToSeq".} = @@ -1456,8 +1458,17 @@ when defined(nimHasTopDownInference): ## ## This is not as efficient as turning a fixed length array into a sequence ## as it always copies every element of `a`. - newSeq(result, a.len) - for i in 0..a.len-1: result[i] = a[i] + let sz = a.len + when supportsCopyMem(T) and not defined(js): + result = newSeqUninit[T](sz) + when nimvm: + for i in 0..sz-1: result[i] = a[i] + else: + if sz != 0: + copyMem(addr result[0], addr a[0], sizeof(T) * sz) + else: + newSeq(result, sz) + for i in 0..sz-1: result[i] = a[i] else: proc `@`*[T](a: openArray[T]): seq[T] = ## Turns an *openArray* into a sequence. @@ -1628,8 +1639,6 @@ when not defined(js) and defined(nimV2): vTable: UncheckedArray[pointer] # vtable for types PNimTypeV2 = ptr TNimTypeV2 -proc supportsCopyMem(t: typedesc): bool {.magic: "TypeTrait".} - when notJSnotNims and defined(nimSeqsV2): include "system/strs_v2" include "system/seqs_v2"