summary refs log tree commit diff stats
path: root/tests/gcbench.nim
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2008-08-23 11:32:48 +0200
committerAndreas Rumpf <rumpf_a@web.de>2008-08-23 11:32:48 +0200
commit972c51086152bd45aef4eb17c099fa3472a19d04 (patch)
tree3e51e4f71f737a4f943bb71cd889d7002c3d4b5a /tests/gcbench.nim
parent07d5a8085bbcc21a1d9d06a2976ecc00e9c8d55b (diff)
downloadNim-972c51086152bd45aef4eb17c099fa3472a19d04.tar.gz
deleted web and dist
Diffstat (limited to 'tests/gcbench.nim')
-rw-r--r--tests/gcbench.nim172
1 files changed, 172 insertions, 0 deletions
diff --git a/tests/gcbench.nim b/tests/gcbench.nim
new file mode 100644
index 000000000..4c94fe360
--- /dev/null
+++ b/tests/gcbench.nim
@@ -0,0 +1,172 @@
+# This is adapted from a benchmark written by John Ellis and Pete Kovac

+#   of Post Communications.

+#   It was modified by Hans Boehm of Silicon Graphics.

+#

+# 	This is no substitute for real applications. No actual application

+#	is likely to behave in exactly this way. However, this benchmark was

+#	designed to be more representative of real applications than other

+#	Java GC benchmarks of which we are aware.

+#	It attempts to model those properties of allocation requests that

+#	are important to current GC techniques.

+#	It is designed to be used either to obtain a single overall performance

+#	number, or to give a more detailed estimate of how collector

+#	performance varies with object lifetimes. It prints the time

+#	required to allocate and collect balanced binary trees of various

+#	sizes. Smaller trees result in shorter object lifetimes. Each cycle

+#	allocates roughly the same amount of memory.

+#	Two data structures are kept around during the entire process, so

+#	that the measured performance is representative of applications

+#	that maintain some live in-memory data. One of these is a tree

+#	containing many pointers. The other is a large array containing

+#	double precision floating point numbers. Both should be of comparable

+#	size.

+#

+#	The results are only really meaningful together with a specification

+#	of how much memory was used. It is possible to trade memory for

+#	better time performance. This benchmark should be run in a 32 MB

+#	heap, though we don't currently know how to enforce that uniformly.

+#

+#	Unlike the original Ellis and Kovac benchmark, we do not attempt

+# measure pause times. This facility should eventually be added back

+#	in. There are several reasons for omitting it for now.  The original

+#	implementation depended on assumptions about the thread scheduler

+#	that don't hold uniformly. The results really measure both the

+#	scheduler and GC. Pause time measurements tend to not fit well with

+#	current benchmark suites. As far as we know, none of the current

+#	commercial Java implementations seriously attempt to minimize GC pause

+#	times.

+#

+#	Known deficiencies:

+#		- 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

+#		  check for proper locking

+#

+

+import

+  strutils, times

+

+type

+  PNode = ref TNode

+  TNode {.final.} = object

+    left, right: PNode

+    i, j: int

+

+proc newNode(l, r: PNode): PNode =

+  new(result)

+  result.left = l

+  result.right = r

+

+const

+  kStretchTreeDepth = 18 # about 16Mb

+  kLongLivedTreeDepth = 16  # about 4Mb

+  kArraySize  = 500000  # about 4Mb

+  kMinTreeDepth = 4

+  kMaxTreeDepth = 16

+

+# Nodes used by a tree of a given size

+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)

+

+# Build tree top down, assigning to older objects.

+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)

+

+# Build tree bottom-up

+proc MakeTree(iDepth: int): PNode =

+  if iDepth <= 0:

+    new(result)

+  else:

+    return newNode(MakeTree(iDepth-1),

+                   MakeTree(iDepth-1))

+

+proc PrintDiagnostics() =

+  var

+    FreeMemory = getFreeMem()

+    TotalMemory = getTotalMem()

+

+  echo("Total memory available: " & $TotalMemory & " bytes")

+  echo("Free memory: " & $FreeMemory & " bytes")

+

+proc TimeConstruction(depth: int) =

+  var

+    root, tempTree: PNode

+    t: int

+    iNumIters: int

+

+  iNumIters = NumIters(depth)

+

+  echo("Creating " & $iNumIters & " trees of depth " & $depth)

+  t = getStartMilsecs()

+  for i in 0..iNumIters-1:

+    new(tempTree)

+    Populate(depth, tempTree)

+    tempTree = nil

+  echo("\tTop down construction took " &

+                     $(getStartMilsecs() - t) & "msecs")

+  t = getStartMilsecs()

+  for i in 0..iNumIters-1:

+    tempTree = MakeTree(depth)

+    tempTree = nil

+  echo("\tBottom up construction took " &

+                     $(getStartMilsecs() - t) & "msecs")

+

+type

+  tMyArray = seq[float]

+

+proc main() =

+  var

+    root, longLivedTree, tempTree: PNode

+    t: int

+    myarray: tMyArray

+

+  echo("Garbage Collector Test")

+  echo(" Stretching memory with a binary tree of depth " &

+       $kStretchTreeDepth)

+  PrintDiagnostics()

+  t = getStartMilsecs()

+

+  # Stretch the memory space quickly

+  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)

+

+  # Create long-lived array, filling half of it

+  echo(" Creating a long-lived array of " & $kArraySize & " doubles")

+  myarray = []

+  setlength(myarray, kArraySize)

+  for i in 0..kArraySize div 2 -1:

+    myarray[i] = 1.0 / toFloat(i)

+

+  PrintDiagnostics()

+

+  var d = kMinTreeDepth

+  while d <= kMaxTreeDepth:

+    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

+

+  var elapsed = getStartMilsecs() - t

+  PrintDiagnostics()

+  echo("Completed in " & $elapsed & "ms.")

+

+main()