digitalmars.D - C faults, etc
- bearophile (25/25) Jul 20 2009 There's a long thread on reddit about the faults of C language:
- BCS (4/21) Jul 20 2009 It would be interesting to write a template that takes a static format s...
- Jarrett Billingsley (4/8) Jul 20 2009 Oh, you mean something like this?
- Daniel Keep (37/71) Jul 20 2009 What are you talking about? There are numerous people complaining that
- bearophile (23/26) Jul 20 2009 This is a first little test, with DMD V.2.031, on Windows, Phobos2:
- Lutger (4/37) Jul 20 2009 writefln does a flush where writef doesn't. On my system (fedora 11) all...
- Lutger (6/6) Jul 20 2009 Oh shit I forgot to redirect. That made my timings useless.
- bearophile (11/14) Jul 20 2009 I am doing such tests on an unloaded Windows 32 bit XP SP2, on a Core2 a...
- Walter Bright (3/14) Jul 20 2009 D's answer to printf and its problems is writefln.
- bearophile (6/8) Jul 20 2009 Thanks god there are people (compiler writers, like GCC devs) that think...
- Walter Bright (4/5) Jul 20 2009 I've implemented printf. There is nothing fundamental about its
- Steven Schveighoffer (17/23) Jul 21 2009 Part of it could be fundamental.
There's a long thread on reddit about the faults of C language: http://www.reddit.com/r/programming/comments/92l8w/in_your_opinions_what_is_wrong_with_the_c/ Some comments derived from it: D already fixes/pathes several problems of C, but not all of them. One of the problems is the pointer syntax and the problem coming from its operator precedence. Pascal pointer syntax is a bit better. The famous "C++ resyntaxed" shows a quite better pointer syntax. I'd like to see a better and less bug-prone pointer syntax in D, but it's hard to change it and keep almost-source-compatibility with C at the same time. ------------ Lint-like programs like Splint (http://www.splint.org ) help avoid some of the problems of C, but from experience I can see people don't use such programs. So D has to contain some of the things done by a lint. One of the important things is a way to add some more semantics to programs, for example to say if two pointers/slices/arrays are surely distinct, and many other things. (So far I have not understood the D stance regarding pointer aliasing). ------------ D has now two switch, both of them faulty. This looks worse than the C situation. I can't appreciate this situation. ------------ C comma operator is bad. Python shows a WAY better way to use commas, but if D wants to keep its almost-source-compatibility with C then Python syntax may be hard to be added. A partial solution I see is just to turn some usages of the comma operator into a compilation error, just like in D it's an error legal C syntax like: int *i, j; ------------ Java shows that undefined behaviour can be avoided with an acceptable cost in performance. So D eventually has to remove all situations where it acts in an undefined way. Where it's really needed some non-standard way to do things can be added. Better to have nonportable things than undefiend things. ------------ writefln, writeln and the things of Tango are nice and cute and safe, but if I have to save 250 MB of numbers (or 1 GB of them, or even more) then performance is important, and those cute functions are 2-3-5 times slower than printf. This means printf can save me minutes of running time. So I use printf. But if I use printf in C and I write: int main() { float f = 1.2345; printf("%d\n", f); return 0; } The compiler says me: warning: format '%d' expects type 'int', but argument 2 has type 'double' While DMD compiles it silently. Better to quickly add such warning/error to D compilers too. Bye, bearophile
Jul 20 2009
Reply to bearophile,writefln, writeln and the things of Tango are nice and cute and safe, but if I have to save 250 MB of numbers (or 1 GB of them, or even more) then performance is important, and those cute functions are 2-3-5 times slower than printf. This means printf can save me minutes of running time. So I use printf. But if I use printf in C and I write: int main() { float f = 1.2345; printf("%d\n", f); return 0; } The compiler says me: warning: format '%d' expects type 'int', but argument 2 has type 'double' While DMD compiles it silently. Better to quickly add such warning/error to D compilers too.It would be interesting to write a template that takes a static format string (using writef syntax) and, based on its argument tuple to generates a trivial wrapper around printf with a guarantied correct (printf syntax) format string.
Jul 20 2009
On Mon, Jul 20, 2009 at 12:22 PM, BCS<ao pathlink.com> wrote:It would be interesting to write a template that takes a static format string (using writef syntax) and, based on its argument tuple to generates a trivial wrapper around printf with a guarantied correct (printf syntax) format string.Oh, you mean something like this? http://github.com/wilkie/xomb/blob/98f612085516d644d03bb464224fa37c9d8f2926/kernel/core/kprintf.d teeheehee
Jul 20 2009
bearophile wrote:There's a long thread on reddit about the faults of C language: http://www.reddit.com/r/programming/comments/92l8w/in_your_opinions_what_is_wrong_with_the_c/ Some comments derived from it: D already fixes/pathes several problems of C, but not all of them. One of the problems is the pointer syntax and the problem coming from its operator precedence. Pascal pointer syntax is a bit better. The famous "C++ resyntaxed" shows a quite better pointer syntax. I'd like to see a better and less bug-prone pointer syntax in D, but it's hard to change it and keep almost-source-compatibility with C at the same time.What are you talking about? There are numerous people complaining that defining pointer types is painful, but D fixes that. There's one person who complained about parsing ambiguities; was that what you were referring to? It doesn't help that you don't specify what the problem is.------------ Lint-like programs like Splint (http://www.splint.org ) help avoid some of the problems of C, but from experience I can see people don't use such programs. So D has to contain some of the things done by a lint. One of the important things is a way to add some more semantics to programs, for example to say if two pointers/slices/arrays are surely distinct, and many other things. (So far I have not understood the D stance regarding pointer aliasing).Neither Lint or Splint was mentioned ONCE in that thread.------------ D has now two switch, both of them faulty. This looks worse than the C situation. I can't appreciate this situation.Switch was brought up exactly once, but that was a comment regarding enums. You also haven't specified what the problem is.------------ C comma operator is bad. Python shows a WAY better way to use commas, but if D wants to keep its almost-source-compatibility with C then Python syntax may be hard to be added. A partial solution I see is just to turn some usages of the comma operator into a compilation error, just like in D it's an error legal C syntax like: int *i, j;Comma operator was never brought up.------------ Java shows that undefined behaviour can be avoided with an acceptable cost in performance. So D eventually has to remove all situations where it acts in an undefined way.While I think it should, I hardly see why the first demands the second.Where it's really needed some non-standard way to do things can be added. Better to have nonportable things than undefiend things.I'm fairly certain Walter has stated numerous times that one of the goals of D is to remove undefined behaviour. Why are you arguing for something which Walter already agrees with you on? One quick query with Google later: "One of the goals of D is to eliminate undefined behavior wherever possible. In C++, the undefined order of static construction was a source of many porting problems. I think it's better in the long run to have a defined order, even if it means having to reorganize the code a bit." http://www.digitalmars.com/d/archives/digitalmars/D/announce/Re_QtD_0.1_is_out_14928.html------------ writefln, writeln and the things of Tango are nice and cute and safe, but if I have to save 250 MB of numbers (or 1 GB of them, or even more) then performance is important, and those cute functions are 2-3-5 times slower than printf. This means printf can save me minutes of running time. So I use printf. But if I use printf in C and I write:Firstly, if they're slower than printf, I imagine something is wrong. In Tango's case, I know it directly calls into the Win32 API. If it's 5 times slower than printf, something is horribly wrong, either with something along the way, or with your code. Did you file a ticket? Actually, let's check... (Goes off to test.) If you naively use tango.io.device.File and, say, to!(char[])(int), then D will take twice as long as C. That's because File is unbuffered and to!(char[])(int) uses a heap allocation. If you use a Buffered stream and use ...convert.Integer.format with a scratch buffer, D ends up being about 10% faster than C. This could be better documented, but Tango is *not* slow when used correctly.int main() { float f = 1.2345; printf("%d\n", f); return 0; } The compiler says me: warning: format '%d' expects type 'int', but argument 2 has type 'double' While DMD compiles it silently. Better to quickly add such warning/error to D compilers too.Why on earth should the D compiler special-case a function that's not even supposed to be used?! D has typesafe variadics and variadic templates.Bye, bearophileNone of these, with the possible exception of the pointer syntax one, had anything to do with that thread, so far as I can see.
Jul 20 2009
Daniel Keep:Why on earth should the D compiler special-case a function that's not even supposed to be used?!<What's the purpose of being able to use the C std lib in D programs if then such functions aren't supposed to be used?Actually, let's check... (Goes off to test.)<This is a first little test, with DMD V.2.031, on Windows, Phobos2: import std.stdio: printf; void main() { const int N = 2_000_000; for (int i; i < N; i++) printf("test %d\n", i); } A second version that uses writefln: import std.stdio: writefln; void main() { const int N = 2_000_000; for (int i; i < N; i++) writefln("test %d", i); } I have redirected their output to a file (26.2 MB file). The timings are: 1.16 seconds for the version with printf, and 14.93 seconds for the version with writefln. ----------------------- BCS:It would be interesting to write a template that takes a static format string (using writef syntax) and, based on its argument tuple to generates a trivial wrapper around printf with a guarantied correct (printf syntax) format string.<A nice idea, thanks. I may do that. Bye, bearophile
Jul 20 2009
bearophile wrote:Daniel Keep:writefln does a flush where writef doesn't. On my system (fedora 11) all timings are nearly the same however, while writef is actually a bit faster than printf. What OS are you on?Why on earth should the D compiler special-case a function that's not even supposed to be used?!<What's the purpose of being able to use the C std lib in D programs if then such functions aren't supposed to be used?Actually, let's check... (Goes off to test.)<This is a first little test, with DMD V.2.031, on Windows, Phobos2: import std.stdio: printf; void main() { const int N = 2_000_000; for (int i; i < N; i++) printf("test %d\n", i); } A second version that uses writefln: import std.stdio: writefln; void main() { const int N = 2_000_000; for (int i; i < N; i++) writefln("test %d", i); } I have redirected their output to a file (26.2 MB file). The timings are: 1.16 seconds for the version with printf, and 14.93 seconds for the version with writefln.
Jul 20 2009
Oh shit I forgot to redirect. That made my timings useless. This one is about 8x faster than writefln, flushing seems to be quite expensive: const int N = 2_000_000; for (int i; i < N; i++) writef("test %d\n", i);
Jul 20 2009
Lutger:writefln does a flush where writef doesn't. On my system (fedora 11) all timings are nearly the same however, while writef is actually a bit faster than printf. What OS are you on?I am doing such tests on an unloaded Windows 32 bit XP SP2, on a Core2 at 2 GHz and 2 GB RAM. I have done another test for writeln, and indeed it's quite faster than writefln, it takes 2.45 seconds: import std.stdio: writeln; void main() { const int N = 2_000_000; for (int i; i < N; i++) writeln("test ", i); } Bye, bearophile
Jul 20 2009
bearophile wrote:writefln, writeln and the things of Tango are nice and cute and safe, but if I have to save 250 MB of numbers (or 1 GB of them, or even more) then performance is important, and those cute functions are 2-3-5 times slower than printf. This means printf can save me minutes of running time. So I use printf. But if I use printf in C and I write: int main() { float f = 1.2345; printf("%d\n", f); return 0; } The compiler says me: warning: format '%d' expects type 'int', but argument 2 has type 'double'This is a non-standard extension to C.While DMD compiles it silently. Better to quickly add such warning/error to D compilers too.D's answer to printf and its problems is writefln.
Jul 20 2009
Walter Bright:This is a non-standard extension to C.Thanks god there are people (compiler writers, like GCC devs) that think the C standard is not a Holy Text given to us by God :-) They improve C where it has holes and limits, so it can be more useful for most practical purposes. Language lawyers can eat their hats. And even if C standard is sacred and you can never touch it, D isn't C, and C functions that can be used from D can keep the C interfaces but improve the situation in some ways.D's answer to printf and its problems is writefln.<Then we have to work on the efficiency of its implementation :-) (See my timings lower in this thread). Bye, bearophile
Jul 20 2009
bearophile wrote:Then we have to work on the efficiency of its implementation :-) (See my timings lower in this thread).I've implemented printf. There is nothing fundamental about its efficiency that would be any better than writefln. If writefln is slower, it's due to a bug, not anything fundamental.
Jul 20 2009
On Mon, 20 Jul 2009 20:41:03 -0400, Walter Bright <newshound1 digitalmars.com> wrote:bearophile wrote:Part of it could be fundamental. * D deals with UTF, whereas printf does not * Phobos calls the C runtime, so it's guaranteed never to beat printf, since printf is not type-safe, and therefore does less. * Both Tango and Phobos output functions make use of delegates to output data. In the case of Phobos, it uses a delegate to call the C runtime's "delegate" fputc, so it's going to be double the delegate penalty for each character. If you're measuring the performance of millions of writes, then you will see even a slight difference. Bearophile, You may want to develop a more specialized function to do file output if you are writing such large quantities of uniform data, calling the system calls directly, it might even beat printf. -SteveThen we have to work on the efficiency of its implementation :-) (See my timings lower in this thread).I've implemented printf. There is nothing fundamental about its efficiency that would be any better than writefln. If writefln is slower, it's due to a bug, not anything fundamental.
Jul 21 2009