[Performance] shootout.binarytrees when implemented with gc is 10x slower than C# on .NET 2.0
Andrey Khropov
andkhropov_nosp at m_mtu-net.ru
Sat Nov 11 15:32:15 PST 2006
Here is the D code for shootout.binarytrees with GC. Absolutely equal to the C#
code (I also embedded a timer):
------------------------------------------------------------------------
import std.c.stdlib, std.stdio, std.perf, std.gc;
int main(char[][] args)
{
int N = args.length > 1 ? atoi(args[1]) : 1;
auto t = new HighPerformanceCounter();
t.start();
int minDepth = 4;
int maxDepth = (minDepth + 2) > N ? minDepth + 2 : N;
int stretchDepth = maxDepth + 1;
TreeNode stretchTree = TreeNode.BottomUpTree(0, stretchDepth);
writefln("stretch tree of depth ",stretchDepth,"\t check:
",stretchTree.ItemCheck);
TreeNode longLivedTree = TreeNode.BottomUpTree(0, maxDepth);
int depth;
for(depth = minDepth; depth <= maxDepth; depth += 2)
{
int check, iterations = 1 << (maxDepth - depth + minDepth);
for(int i = 1; i <= iterations; i++)
{
auto tempTree = TreeNode.BottomUpTree(i, depth);
check += tempTree.ItemCheck;
//delete tempTree;
tempTree = TreeNode.BottomUpTree(-i, depth);
check += tempTree.ItemCheck;
//delete tempTree;
}
writefln(iterations * 2,"\t trees of depth ",depth,"\t check: ",check);
}
writefln("long lived tree of depth ",maxDepth,"\t check:
",longLivedTree.ItemCheck);
t.stop();
writefln(t.milliseconds()," ms elapsed.");
return 0;
}
class TreeNode
{
public:
this(int item, TreeNode left = null, TreeNode right = null)
{
this.item = item;
this.left = left;
this.right = right;
}
static TreeNode BottomUpTree(int item, int depth)
{
if(depth > 0)
return new TreeNode(item
,BottomUpTree(2 * item - 1, depth - 1)
,BottomUpTree(2 * item, depth - 1));
return new TreeNode(item);
}
int ItemCheck()
{
if(left)
return item + left.ItemCheck() - right.ItemCheck();
return item;
}
private:
TreeNode left, right;
int item;
}
------------------------------------------------------------------------
Here's the C# code (also with embedded timer):
------------------------------------------------------------------------
using System;
using System.Diagnostics;
class BinaryTrees
{
const int minDepth = 4;
public static void Main(String[] args)
{
int n = 0;
if (args.Length > 0) n = Int32.Parse(args[0]);
Stopwatch t = new Stopwatch();
t.Start();
int maxDepth = Math.Max(minDepth + 2, n);
int stretchDepth = maxDepth + 1;
int check = (TreeNode.bottomUpTree(0,stretchDepth)).itemCheck();
Console.WriteLine("stretch tree of depth {0}\t check: {1}", stretchDepth,
check);
TreeNode longLivedTree = TreeNode.bottomUpTree(0,maxDepth);
for (int depth=minDepth; depth<=maxDepth; depth+=2){
int iterations = 1 << (maxDepth - depth + minDepth);
check = 0;
for (int i=1; i<=iterations; i++)
{
check += (TreeNode.bottomUpTree(i,depth)).itemCheck();
check += (TreeNode.bottomUpTree(-i,depth)).itemCheck();
}
Console.WriteLine("{0}\t trees of depth {1}\t check: {2}",
iterations*2, depth, check);
}
Console.WriteLine("long lived tree of depth {0}\t check: {1}",
maxDepth, longLivedTree.itemCheck());
t.Stop();
Console.WriteLine(t.ElapsedMilliseconds + "ms elapsed.");
}
class TreeNode
{
private TreeNode left, right;
private int item;
TreeNode(int item){
this.item = item;
}
TreeNode(int item,TreeNode left, TreeNode right){
this.left = left;
this.right = right;
this.item = item;
}
internal static TreeNode bottomUpTree(int item, int depth){
if (depth>0){
return new TreeNode(
item,
bottomUpTree(2*item-1, depth-1),
bottomUpTree(2*item, depth-1)
);
}
else {
return new TreeNode(item);
}
}
internal int itemCheck(){
// if necessary deallocate here
if (left==null) return item;
else return item + left.itemCheck() - right.itemCheck();
}
}
}
------------------------------------------------------------------------
So the results are (with cmdline parameter = 16):
C# on .NET 2.0 : 1.902 sec
DMD 0.173 - malloc(original version) : 5.189 sec
C# on Mono 1.1.18 : 6.630 sec
DMD 0.173 - full GC : 19.720 sec
--
AKhropov
More information about the Digitalmars-d
mailing list