A smaller GC benchmark
bearophile
bearophileHUGS at lycos.com
Mon Dec 10 08:56:10 PST 2007
This tiny benchmark focus on GC performance and shows similar results to the "binary trees" benchmark I have shown here few weeks ago, but it's quite shorter, so it may be more useful. This code isn't meant to represent normal programs with thousands of classes, etc, it just shows something quite limited. This is an adaptation of the "Object Test" that you can find used and discussed here:
http://www.twistedmatrix.com/users/glyph/rant/python-vs-java.html
http://blog.snaplogic.org/?p=55
http://programming.reddit.com/info/24ynh/comments
Note that I test the GC of Phobos only, I don't use Tango yet.
Object Test timings (on PIII @ 500 MHz), best of 3 runs (seconds, approximate Mbytes memory used), n=1_000, m=10_000:
seconds MB
DMD class: 18.95 1.7
GDC class: 17.91 1.8
DMD struct: 11.77 1.7
GDC struct: 12.31 1.8
Python: 37.10 3.1 (ShedSkin version)
Psyco: 15.68 3.5
ShedSkin 6.35 1.6
Java (1): 2.19 7.3
Java (2): 2.10 7.8
See below for the sources. You can see the Java is about 9 (~= 18.95 / 2.10) times faster than the program produced by DMD. Even Psyco (the JIT for the turtle-slow language Python) gives faster performance (and the Python GC is simple, it's just a reference count plus cycle detection). You can also see Java (as usual) uses much more RAM (7.8/1.7 ~= 4.6).
Note that with some manual GC optimization the running time for the DMD class benchmark can become about one-two seconds smaller, but the memory used can be about 4 MB:
import std.gc;
class ObjectTest { ObjectTest next; }
void main() {
for (uint k = 0; k < 50; k++) {
std.gc.disable();
for (uint i = 0; i < 20; i++) {
auto root = new ObjectTest();
for (uint j = 0; j < 10_000; j++) {
root.next = new ObjectTest();
root = root.next;
}
}
std.gc.fullCollect();
}
}
-------------------
COMPILED/RUN WITH:
gcc version 3.4.5 (mingw special) (gdc 0.24, using dmd 1.020)
DMD v1.024
gcc version 3.4.2 (mingw-special)
javac 1.6.0_03
java version "1.6.0_03"
Python 2.5.1
ShedSkin 0.0.25 (shedskin.sourceforge.net , a Python to C++ compiler)
-------------------
COMPILATION/RUNNING PARAMETERS:
GDC used as:
gdc -O3 -s -frelease -finline-functions -ffast-math -fomit-frame-pointer -funroll-loops -march=pentiumpro obj_test_class.d -o obj_test_class_gdc
DMD used as:
dmd -O -release -inline obj_test_class.d -ofobj_test_class_dmd.exe
Java compiled with:
javac ObjectTest.java
Java (1) run with:
java ObjectTest
Java (2) run with:
java -Xms20m -Xbatch ObjectTest
SS and Psyco compiled and run without flags.
-------------------
SOURCES:
// obj_test_class.d
class ObjectTest { ObjectTest next; }
void main() {
for (uint i = 0; i < 1_000; i++) {
auto root = new ObjectTest();
for (uint j = 0; j < 10_000; j++) {
root.next = new ObjectTest();
root = root.next;
}
}
}
-------------------
// obj_test_struct.d
struct ObjectTest { ObjectTest* next; }
void main() {
for (uint i = 0; i < 1_000; i++) {
auto root = new ObjectTest();
for (uint j = 0; j < 10_000; j++) {
root.next = new ObjectTest();
root = root.next;
}
}
}
-------------------
// ObjectTest.java
public class ObjectTest {
public ObjectTest next;
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
ObjectTest root = new ObjectTest();
for (int j = 0; j < 10000; j++) {
root.next = new ObjectTest();
root = root.next;
}
}
}
}
-------------------
# obj_test.py
from psyco.classes import __metaclass__
class ObjectTest: pass
def main():
for i in xrange(1000): # N
root = ObjectTest()
for j in xrange(10000): # M
root.next = ObjectTest()
root = root.next
import psyco; psyco.full()
main()
-------------------
# obj_test_ss.py
class ObjectTest: pass
def main():
for i in xrange(1000): # N
root = ObjectTest()
for j in xrange(10000): # M
root.next = ObjectTest()
root = root.next
main()
Bear hugs,
bearophile
More information about the Digitalmars-d
mailing list