summary refs log tree commit diff stats
path: root/tests/gc/gcbench.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tests/gc/gcbench.nim')
-rw-r--r--tests/gc/gcbench.nim86
1 files changed, 49 insertions, 37 deletions
diff --git a/tests/gc/gcbench.nim b/tests/gc/gcbench.nim
index 782daf793..e29ea762d 100644
--- a/tests/gc/gcbench.nim
+++ b/tests/gc/gcbench.nim
@@ -44,7 +44,7 @@ discard """
 # - No way to check on memory use
 # - No cyclic data structures
 # - No attempt to measure variation with object size
-# - Results are sensitive to locking cost, but we dont
+# - Results are sensitive to locking cost, but we don't
 #   check for proper locking
 #
 
@@ -53,11 +53,11 @@ import
 
 type
   PNode = ref TNode
-  TNode {.final.} = object
+  TNode {.final, acyclic.} = object
     left, right: PNode
     i, j: int
 
-proc newNode(L, r: PNode): PNode =
+proc newNode(L, r: sink PNode): PNode =
   new(result)
   result.left = L
   result.right = r
@@ -65,55 +65,58 @@ proc newNode(L, r: PNode): PNode =
 const
   kStretchTreeDepth = 18 # about 16Mb
   kLongLivedTreeDepth = 16  # about 4Mb
-  kArraySize  = 500000  # about 4Mb
+  kArraySize = 500000  # about 4Mb
   kMinTreeDepth = 4
   kMaxTreeDepth = 16
 
+when not declared(withScratchRegion):
+  template withScratchRegion(body: untyped) = body
+
 # Nodes used by a tree of a given size
-proc TreeSize(i: int): int = return ((1 shl (i + 1)) - 1)
+proc treeSize(i: int): int = return ((1 shl (i + 1)) - 1)
 
 # Number of iterations to use for a given tree depth
-proc NumIters(i: int): int =
-  return 2 * TreeSize(kStretchTreeDepth) div TreeSize(i)
+proc numIters(i: int): int =
+  return 2 * treeSize(kStretchTreeDepth) div treeSize(i)
 
 # Build tree top down, assigning to older objects.
-proc Populate(iDepth: int, thisNode: PNode) =
+proc populate(iDepth: int, thisNode: PNode) =
   if iDepth <= 0:
     return
   else:
     new(thisNode.left)
     new(thisNode.right)
-    Populate(iDepth-1, thisNode.left)
-    Populate(iDepth-1, thisNode.right)
+    populate(iDepth-1, thisNode.left)
+    populate(iDepth-1, thisNode.right)
 
 # Build tree bottom-up
-proc MakeTree(iDepth: int): PNode =
+proc makeTree(iDepth: int): PNode =
   if iDepth <= 0:
     new(result)
   else:
-    return newNode(MakeTree(iDepth-1), MakeTree(iDepth-1))
+    return newNode(makeTree(iDepth-1), makeTree(iDepth-1))
 
-proc PrintDiagnostics() =
-  echo("Total memory available: " & $getTotalMem() & " bytes")
-  echo("Free memory: " & $getFreeMem() & " bytes")
+proc printDiagnostics() =
+  echo("Total memory available: " & formatSize(getTotalMem()) & " bytes")
+  echo("Free memory: " & formatSize(getFreeMem()) & " bytes")
 
-proc TimeConstruction(depth: int) =
+proc timeConstruction(depth: int) =
   var
     root, tempTree: PNode
     iNumIters: int
 
-  iNumIters = NumIters(depth)
+  iNumIters = numIters(depth)
 
   echo("Creating " & $iNumIters & " trees of depth " & $depth)
   var t = epochTime()
   for i in 0..iNumIters-1:
     new(tempTree)
-    Populate(depth, tempTree)
+    populate(depth, tempTree)
     tempTree = nil
   echo("\tTop down construction took " & $(epochTime() - t) & "msecs")
   t = epochTime()
   for i in 0..iNumIters-1:
-    tempTree = MakeTree(depth)
+    tempTree = makeTree(depth)
     tempTree = nil
   echo("\tBottom up construction took " & $(epochTime() - t) & "msecs")
 
@@ -127,42 +130,51 @@ proc main() =
 
   echo("Garbage Collector Test")
   echo(" Stretching memory with a binary tree of depth " & $kStretchTreeDepth)
-  PrintDiagnostics()
+  printDiagnostics()
   var t = epochTime()
 
   # Stretch the memory space quickly
-  tempTree = MakeTree(kStretchTreeDepth)
-  tempTree = nil
+  withScratchRegion:
+    tempTree = makeTree(kStretchTreeDepth)
+    tempTree = nil
 
   # Create a long lived object
   echo(" Creating a long-lived binary tree of depth " &
         $kLongLivedTreeDepth)
   new(longLivedTree)
-  Populate(kLongLivedTreeDepth, longLivedTree)
+  populate(kLongLivedTreeDepth, longLivedTree)
 
   # Create long-lived array, filling half of it
   echo(" Creating a long-lived array of " & $kArraySize & " doubles")
-  newSeq(myarray, kArraySize)
-  for i in 0..kArraySize div 2 - 1:
-    myarray[i] = 1.0 / toFloat(i)
+  withScratchRegion:
+    newSeq(myarray, kArraySize)
+    for i in 0..kArraySize div 2 - 1:
+      myarray[i] = 1.0 / toFloat(i)
 
-  PrintDiagnostics()
+    printDiagnostics()
 
-  var d = kMinTreeDepth
-  while d <= kMaxTreeDepth:
-    TimeConstruction(d)
-    inc(d, 2)
+    var d = kMinTreeDepth
+    while d <= kMaxTreeDepth:
+      withScratchRegion:
+        timeConstruction(d)
+      inc(d, 2)
 
-  if longLivedTree == nil or myarray[1000] != 1.0/1000.0:
-    echo("Failed")
-    # fake reference to LongLivedTree
-    # and array to keep them from being optimized away
+    if longLivedTree == nil or myarray[1000] != 1.0/1000.0:
+      echo("Failed")
+      # fake reference to LongLivedTree
+      # and array to keep them from being optimized away
 
   var elapsed = epochTime() - t
-  PrintDiagnostics()
-  echo("Completed in " & $elapsed & "ms. Success!")
+  printDiagnostics()
+  echo("Completed in " & $elapsed & "s. Success!")
+  when declared(getMaxMem):
+    echo "Max memory ", formatSize getMaxMem()
 
 when defined(GC_setMaxPause):
   GC_setMaxPause 2_000
 
+when defined(gcDestructors):
+  let mem = getOccupiedMem()
 main()
+when defined(gcDestructors):
+  doAssert getOccupiedMem() == mem