print function

cy via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Feb 4 23:04:27 PST 2016


On Thursday, 4 February 2016 at 15:32:48 UTC, Artur Skawina wrote:
>    void print(A...)(A a) {
>       foreach (N, ref e; a)
>          write(e, N==A.length-1?"\n":" ");
>    }

>>will be unrolled at compile time

Mind if I elaborate on this a bit? If that is unrolled, I 
understand it will unroll into several calls to write, as in 
print("1","2","3") => write("1"," ");write("2"," 
");write("3","\n");

And presumably, write() unrolls its arguments too. Each string 
argument to write() unrolls to a put(). And put("abc") unrolls 
into put("a");put("b");put("c"), each of which that call the C 
routine fwrite with a length 1.

So the above print, if you did print("hi","there") it would become
write("hi"," "); write("there","\n")
which would become
put("hi");put(" ");put("there");put("\n");
which would become
put("h");put("i");put(" 
");put("t");put("h");put("e");put("r");put("e");put("\n");

And then it compiles.

Any literal string you pass to std.stdio.write will be expanded 
into 1 fwrite invocation per character. And 
std.format.formattedWrite is called on aggregate types like 
lists, which stringifies each value, and passes the string to 
put(), resulting in again, 1 fwrite per character.

Why put() doesn't just call fwrite without expanding into 1 
character strings, I have no idea. Something with wide 
characters, I guess? But even then it could use one fwrite for 
normal characters. It's not like
fwrite("a",1,1,stdout);fwrite("b",1,1,stdout);
will fail any less if the output stream dies before "b" than
fwrite("ab",2,1,stdout);

Why put() doesn't call the C "fputc" function for 1 character 
strings, I *really* have no idea.

Seems to me some fancy code generation producing write("a"," ", 
"b", " ", "c", "\n") or even put("a b c\n") would still expand 
into 1 put() per character, before it finished compiling.

tl;dr speed demons use std.stream.InputStream.read() whenever you 
can, and std.stream.OutputStream.write() its result. Don't expect 
std.stdio to let you have nice things. std.file.write is always 
preferable if you can generate the whole file beforehand.


More information about the Digitalmars-d-learn mailing list