On Thursday, 12 November 2015 at 11:59:50 UTC, Daniel Kozak wrote:
code:
import std.stdio;
auto fmttable(immutable(string[][]) table) {
import std.array : appender, uninitializedArray;
import std.range : take, repeat;
import std.exception : assumeUnique;
auto res = appender(uninitializedArray!(char[])(128));
res.clear();
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 ~= "|";
foreach (colnum, cell; row) {
int l = widths[colnum] - cast(int)cell.length;
res ~= cell;
if (l)
res ~= ' '.repeat().take(l);
res ~= "|";
}
res.put("\n");
}
return res.data.assumeUnique();
}
void main() {
immutable 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"],
];
writeln(fmttable(table));
int i;
for (i=0; i < 1000000; ++i) {
fmttable(table);
}
writeln(i);
}
timings:
DMD (-O -release -inline -boundscheck=off):
real 0m0.003s
user 0m0.000s
sys 0m0.000s
LDMD2-ldc2 (-O -release -inline -boundscheck=off):
real 0m1.071s
user 0m1.067s
sys 0m0.000s
GDC (-O3 -finline -frelease -fno-bounds-check):
real 0m0.724s
user 0m0.720s
sys 0m0.003s
To test the speed of fmttable itself I split fmttable and main in
to different modules, made fmttable extern(C) so I could just
prototype it in the main module (no import), then compiled them
separately before linking. This should prevent any possible
inlining/purity cleverness. ~1s for ldmd2, ~2s for dmd, which is
business as normal.
dmd is being clever and spotting that fmttable is pure, it would
be good if ldc/gdc could spot this to.