On Tuesday, 25 March 2014 at 02:25:57 UTC, Jay Norwood wrote:
not through yet with the diamond. This one is a little faster.
Appending the newline to the stars and calculating the slice
backward from the end would save a w.put for the newlines ...
probably faster. I keep looking for a way to create a dynamic
array of a specific size, filled with the init value I provide.
Does it exist?
D:\diamond\diamond\diamond\Release>diamond 1>nul
brad: time: 19370[ms]
printDiamond1: time: 1140[ms]
printDiamond2: time: 1631[ms]
printDiamond3: time: 633[ms]
jay1: time: 459[ms]
sergei: time: 11886[ms]
jay2: time: 415[ms]
diamondShape: time: 4553[ms]
printDiamond: time: 187[ms]
printDiamonde2a: time: 139[ms]
void printDiamonde2a(in uint N)
{
size_t N2 = N/2;
char pSpace[] = uninitializedArray!(char[])(N2);
pSpace[] = ' ';
char pStars[] = uninitializedArray!(char[])(N);
pStars[] = '*';
char pNewLine[]=uninitializedArray!(char[])(2);
pNewLine[] = '\n';
auto w = appender!(char[])();
w.reserve(N*4);
foreach (n ; 0 .. N2 + 1){
w.put(pSpace[0 .. N2 - n]);
w.put(pStars[0 .. 2*n+1]);
w.put(pNewLine[1]);
}
foreach_reverse (n ; 0 .. N2){
w.put(pSpace[0 .. N2 - n]);
w.put(pStars[0 .. 2*n+1]);
w.put(pNewLine[1]);
}
write(w.data);
}
Interesting. I'd have thought the "extra copy" would be an
overall slowdown, but I guess that's not the case.
I also tried your strategy of adding '\n' to the buffer, but I
was getting some bad output on windows. I'm not sure why "\n\n"
works though. On *nix, I'd have also expected a double line feed.
Did you check the actual output?
Appender is better than "~=", but it's not actually that good
either. Try this:
//----
void printDiamond3(size_t N)
{
import core.memory;
char* p = cast(char*)GC.malloc(N*N+16);
p[0..N*N+16]='*';
auto pp = p;
N/=2;
enum code = q{
pp[0 .. N - n] = ' ';
pp+=(1+N+n);
version(Windows)
{
pp[0 .. 2] = "\r\n";
pp+=2;
}
else
{
pp[0] = '\n';
++pp;
}
};
foreach (n; 0 .. N + 1) {mixin(code);}
foreach_reverse(n; 0 .. N ) {mixin(code);}
write(p[0 .. pp-p]);
}
//----
This makes just 1 allocation of roughly the right size. It also
eagerly fills the entire array with '*', since I *figure* that's
faster than a lot of different writes.
I could be mistaken about that though, but I imagine the
pre-allocation and not using Appender is definitely a boost.