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