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