mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-12 14:23:45 +00:00
fixes #24402 ```nim iterator myPairsInline*[T](twoDarray: seq[seq[T]]): (int, seq[T]) {.inline.} = for indexValuePair in twoDarray.pairs: yield indexValuePair proc innerTestTotalMem() = var my2dArray: seq[seq[int32]] = @[] # fill with some data... for i in 0'i32..100: var z = @[i, i+1] my2dArray.add z for oneDindex, innerArray in myPairsInline(my2dArray): discard innerTestTotalMem() ``` In `for oneDindex, innerArray in myPairsInline(my2dArray)`, `oneDindex` and `innerArray` becomes `cursors` because they satisfy the criterion of `isSimpleIteratorVar`. On the one hand, it is not correct to have them point to the temporary generated by tuple unpacking, which left the memory of the temporary uncleaned up. On the other hand, we don't need to generate a temporary for a symbol node when unpacking the tuple.
54 lines
1.5 KiB
Nim
54 lines
1.5 KiB
Nim
discard """
|
|
joinable: false
|
|
"""
|
|
|
|
# bug #24402
|
|
|
|
iterator myPairsInline*[T](twoDarray: seq[seq[T]]): (int, seq[T]) {.inline.} =
|
|
for indexValuePair in twoDarray.pairs:
|
|
yield indexValuePair
|
|
|
|
iterator myPairsClosure*[T](twoDarray: seq[seq[T]]): (int, seq[T]) {.closure.} =
|
|
for indexValuePair in twoDarray.pairs:
|
|
yield indexValuePair
|
|
|
|
template testTotalMem(iter: untyped): int =
|
|
proc innerTestTotalMem(): int {.gensym.} =
|
|
result = 0
|
|
|
|
# do the same operation 100 times, which should have similar mem footprint
|
|
# as doing it once.
|
|
for iterNum in 0..100:
|
|
result = max(result, getTotalMem()) # record current mem footprint
|
|
|
|
# initialize nested sequence
|
|
var my2dArray: seq[seq[int32]] = @[]
|
|
|
|
# fill with some data...
|
|
for i in 0'i32..10_000:
|
|
var z = @[i, i+1]
|
|
my2dArray.add z
|
|
|
|
# use that data somehow...
|
|
var otherContainer: seq[int32] = @[]
|
|
var count = 0'i32
|
|
for oneDindex, innerArray in my2dArray.iter:
|
|
for value in innerArray:
|
|
inc count
|
|
if oneDindex > 50 and value < 200:
|
|
otherContainer.add count
|
|
|
|
innerTestTotalMem()
|
|
|
|
proc main =
|
|
let closureMem = testTotalMem(myPairsClosure) #1052672
|
|
let inlineMem = testTotalMem(myPairsInline) #20328448
|
|
|
|
when defined(echoFootprint):
|
|
echo "Closure memory footprint: " & $closureMem
|
|
echo "Inline memory footprint: " & $inlineMem
|
|
|
|
# check that mem footprint is relatively similar b/t each method
|
|
doAssert (closureMem - inlineMem).abs < (closureMem div 10)
|
|
|
|
main() |