my first D program (and benchmark against perl)
Daniel Kozak via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Nov 12 01:58:28 PST 2015
V Thu, 12 Nov 2015 09:12:32 +0000
Daniel Kozak via Digitalmars-d-learn
<digitalmars-d-learn at puremagic.com> napsáno:
> 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);
> }
> }
>
>
or with ~ operator:
import std.stdio;
auto fmttable(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() {
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);
}
}
More information about the Digitalmars-d-learn
mailing list