On Wednesday, 11 November 2015 at 13:32:00 UTC, perlancar wrote:
Here's my first non-hello-world D program, which is a direct
translation from the Perl version. I was trying to get a feel
about D's performance:
...
While I am quite impressed with how easy I was able to write D,
I am not so impressed with the performance. Using rdmd (build
20151103), the D program runs in 17.127s while the Perl version
runs in 11.391s (so the D version is quite a bit *slower* than
Perl's). While using gdc (Debian 4.9.2-10), I am able to run it
in 3.988s (only about 3x faster than Perl's version).
I understand that string processing (concatenation, allocation)
is quite optimized in Perl, I was wondering if the D version
could still be sped up significantly?
Main problem is with allocations and with stripLeft, here is my
version which is 10x faster than perls even with DMD. With LDC is
12x faster
import std.stdio;
import std.array : appender;
import std.range;
auto fmttable(T)(T table) {
auto res = appender!(string)();
res.reserve(64);
if (table.length == 0) return "";
// column widths
auto widths = new int[](table[0].length);
foreach (rownum, row; table) {
foreach (colnum, cell; row) {
if (cell.length > widths[colnum])
widths[colnum] = cast(int)cell.length;
}
}
foreach (row; table) {
res.put("|");
foreach (colnum, cell; row) {
int l = widths[colnum] - cast(int)cell.length;
res.put(cell);
if (l)
res.put(' '.repeat().take(l));
res.put("|");
}
res.put("\n");
}
return res.data;
}
void main() {
auto table = [
["row1.1", "row1.2 ", "row1.3"],
["row2.1", "row2.2", "row2.3"],
["row3.1", "row3.2", "row3.3 "],
["row4.1", "row4.2", "row4.3"],
["row5.1", "row5.2", "row5.3"],
];
write(fmttable(table));
for (int i=0; i < 1000000; ++i) {
fmttable(table);
}
}