Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing the performance of d, java and cpp in microbenchmarks

branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 lib
Octocat-spinner-32 src
Octocat-spinner-32 .classpath
Octocat-spinner-32 .gitignore
Octocat-spinner-32 .project
Octocat-spinner-32 CreateDataFiles.launch
Octocat-spinner-32 README.md
Octocat-spinner-32 Rakefile.rb
Octocat-spinner-32 ReadBytes1.launch
Octocat-spinner-32 ReadBytes2.launch
README.md

Performance Microbenchmarks (CPP vs. D)

Background

While testing my protobuf binding for d I observed massive performance degradiation compared to the java protobuf binding, and when I compared with the C++ protobuf binding I run away screaming. It was many times slower than java (not to speak of cpp). I improved the d performance a lot by adjusting my code generator, but after a while I was still too slow. So I wrote some small examples, which do stress the basics of protobuf processing.

Makefile

The Makefile generates the protobuf java sources, needed for the testdata.

CreateDataFiles

This small java programm creates the datafiles in /tmp that are used by the cpp and d implementations.

ReadBytes

This set of implementations tries to read a file from /tmp as fast as possible under the constraint, that the data is pushed to the application byte by byte. This is done 10 times.

Solution bytes read (should be 128863360) Time in ms for a file of size 12886336 Description
g++-1(count) 128863360 115 straight forward implementation using fread with buffering.
llvm-c++-1(count) 128863360 157 straight forward implementation using fread with buffering.
g++-2(count) 128863360 86 straight forward implementation using mmap.
llvm-c++-2(count) 128863360 153 straight forward implementation using mmap.
g++-3(count) 128863360 953 using plain fgetc.
llvm-c++-3(count) 128863360 953 using plain fgetc.
g++-3(count) 128863360 277 using plain fgetc_unlocked.
llvm-c++-3(count) 128863360 404 using plain fgetc_unlocked.
g++-5(count) 128863360 116 using dlopen("libc.so.6") and dlsym("fread").
llvm-c++-5(count) 128863360 159 using dlopen("libc.so.6") and dlsym("fread").
g++-1(sum) 14577336640 161 straight forward implementation using fread with buffering.
llvm-c++-1(sum) 14577336640 233 straight forward implementation using fread with buffering.
g++-2(sum) 14577336640 153 straight forward implementation using mmap.
llvm-c++-2(sum) 14577336640 154 straight forward implementation using mmap.
g++-3(sum) 14577336640 990 using plain fgetc.
llvm-c++-3(sum) 14577336640 968 using plain fgetc.
g++-3(sum) 14577336640 281 using plain fgetc_unlocked.
llvm-c++-3(sum) 14577336640 627 using plain fgetc_unlocked.
g++-5(sum) 14577336640 170 using dlopen("libc.so.6") and dlsym("fread").
llvm-c++-5(sum) 14577336640 211 using dlopen("libc.so.6") and dlsym("fread").
d2-Digital Mars D-1(count) 128863360 1802 using std.stream.BufferedFile with ubyte[1].
d2-LDC-1(count) 128863360 12515 using std.stream.BufferedFile with ubyte[1].
d2-GDC-1(count) 128863360 1504 using std.stream.BufferedFile with ubyte[1].
d2-Digital Mars D-2(count) 128863360 546 using std.c.stdio.fread with buffering (returning nr of bytes and taking a naked ptr for the result).
d2-LDC-2(count) 128863360 115 using std.c.stdio.fread with buffering (returning nr of bytes and taking a naked ptr for the result).
d2-GDC-2(count) 128863360 116 using std.c.stdio.fread with buffering (returning nr of bytes and taking a naked ptr for the result).
d2-Digital Mars D-3(count) 128863360 498 using std.c.stdio.fread with buffering (result is false for eof and returnvalue is an out-param).
d2-LDC-3(count) 128863360 117 using std.c.stdio.fread with buffering (result is false for eof and returnvalue is an out-param).
d2-GDC-3(count) 128863360 116 using std.c.stdio.fread with buffering (result is false for eof and returnvalue is an out-param).
d2-Digital Mars D-4(count) 128863360 496 using std.c.stdio.fread with a semantic like java (return -1 for eof).
d2-LDC-4(count) 128863360 333 using std.c.stdio.fread with a semantic like java (return -1 for eof).
d2-GDC-4(count) 128863360 116 using std.c.stdio.fread with a semantic like java (return -1 for eof).
d2-Digital Mars D-5(count) 128863360 486 using mmfile and a direct pointer to the slice.
d2-LDC-5(count) 128863360 149 using mmfile and a direct pointer to the slice.
d2-GDC-5(count) 128863360 85 using mmfile and a direct pointer to the slice.
d2-Digital Mars D-6(count) 128863360 596 using std.stdio.File with arrayslicing.
d2-LDC-6(count) 128863360 334 using std.stdio.File with arrayslicing.
d2-GDC-6(count) 128863360 160 using std.stdio.File with arrayslicing.
d2-Digital Mars D-7(count) 128863360 740 using dlopen("libc") and dlsym("fread").
d2-LDC-7(count) 128863360 115 using dlopen("libc") and dlsym("fread").
d2-GDC-7(count) 128863360 115 using dlopen("libc") and dlsym("fread").
d2-Digital Mars D-1(sum) 14577336640 1790 using std.stream.BufferedFile with ubyte[1].
d2-LDC-1(sum) 14577336640 12541 using std.stream.BufferedFile with ubyte[1].
d2-GDC-1(sum) 14577336640 1546 using std.stream.BufferedFile with ubyte[1].
d2-Digital Mars D-2(sum) 14577336640 720 using std.c.stdio.fread with buffering (returning nr of bytes and taking a naked ptr for the result).
d2-LDC-2(sum) 14577336640 157 using std.c.stdio.fread with buffering (returning nr of bytes and taking a naked ptr for the result).
d2-GDC-2(sum) 14577336640 157 using std.c.stdio.fread with buffering (returning nr of bytes and taking a naked ptr for the result).
d2-Digital Mars D-3(sum) 14577336640 741 using std.c.stdio.fread with buffering (result is false for eof and returnvalue is an out-param).
d2-LDC-3(sum) 14577336640 157 using std.c.stdio.fread with buffering (result is false for eof and returnvalue is an out-param).
d2-GDC-3(sum) 14577336640 160 using std.c.stdio.fread with buffering (result is false for eof and returnvalue is an out-param).
d2-Digital Mars D-4(sum) 14577336640 455 using std.c.stdio.fread with a semantic like java (return -1 for eof).
d2-LDC-4(sum) 14577336640 297 using std.c.stdio.fread with a semantic like java (return -1 for eof).
d2-GDC-4(sum) 14577336640 160 using std.c.stdio.fread with a semantic like java (return -1 for eof).
d2-Digital Mars D-5(sum) 14577336640 443 using mmfile and a direct pointer to the slice.
d2-LDC-5(sum) 14577336640 190 using mmfile and a direct pointer to the slice.
d2-GDC-5(sum) 14577336640 106 using mmfile and a direct pointer to the slice.
d2-Digital Mars D-6(sum) 14577336640 669 using std.stdio.File with arrayslicing.
d2-LDC-6(sum) 14577336640 336 using std.stdio.File with arrayslicing.
d2-GDC-6(sum) 14577336640 202 using std.stdio.File with arrayslicing.
d2-Digital Mars D-7(sum) 14577336640 732 using dlopen("libc") and dlsym("fread").
d2-LDC-7(sum) 14577336640 157 using dlopen("libc") and dlsym("fread").
d2-GDC-7(sum) 14577336640 160 using dlopen("libc") and dlsym("fread").
java-1 128863360 3025 using BufferedInputStream.read().
java-2 128863360 339 using a read into a buffer[1] with buffering.
java-3 128863360 261 using nio and terminating with BufferUnderflowException.

Outlook

As you can see, most of the d solutions are slower than java or c++. Only if you choose the right implementation for the right compiler similar results to g++ can be expected. Please help me improve / enhance the solutions.

Something went wrong with that request. Please try again.