Skip to content

Commit e79d320

Browse files
committed
Optimize @, fixes #25063
1 parent cd806f9 commit e79d320

File tree

1 file changed

+14
-4
lines changed

1 file changed

+14
-4
lines changed

lib/system.nim

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1465,15 +1465,27 @@ proc isNil*[T: proc | iterator {.closure.}](x: T): bool {.noSideEffect, magic: "
14651465
## Fast check whether `x` is nil. This is sometimes more efficient than
14661466
## `== nil`.
14671467

1468+
proc supportsCopyMem(t: typedesc): bool {.magic: "TypeTrait".}
1469+
14681470
when defined(nimHasTopDownInference):
14691471
# magic used for seq type inference
14701472
proc `@`*[T](a: openArray[T]): seq[T] {.magic: "OpenArrayToSeq".} =
14711473
## Turns an *openArray* into a sequence.
14721474
##
14731475
## This is not as efficient as turning a fixed length array into a sequence
14741476
## as it always copies every element of `a`.
1475-
newSeq(result, a.len)
1476-
for i in 0..a.len-1: result[i] = a[i]
1477+
let sz = a.len
1478+
when supportsCopyMem(T) and not defined(js):
1479+
when nimvm:
1480+
newSeq(result, sz)
1481+
for i in 0..sz-1: result[i] = a[i]
1482+
else:
1483+
result = newSeqUninit[T](sz)
1484+
if sz != 0:
1485+
copyMem(addr result[0], addr a[0], sizeof(T) * sz)
1486+
else:
1487+
newSeq(result, sz)
1488+
for i in 0..sz-1: result[i] = a[i]
14771489
else:
14781490
proc `@`*[T](a: openArray[T]): seq[T] =
14791491
## Turns an *openArray* into a sequence.
@@ -1644,8 +1656,6 @@ when not defined(js) and defined(nimV2):
16441656
vTable: UncheckedArray[pointer] # vtable for types
16451657
PNimTypeV2 = ptr TNimTypeV2
16461658

1647-
proc supportsCopyMem(t: typedesc): bool {.magic: "TypeTrait".}
1648-
16491659
when notJSnotNims and defined(nimSeqsV2):
16501660
include "system/strs_v2"
16511661
include "system/seqs_v2"

0 commit comments

Comments
 (0)