From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Delivered-To: caml-list@yquem.inria.fr Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by yquem.inria.fr (Postfix) with ESMTP id 19248BC8B for ; Sat, 12 Feb 2005 16:18:52 +0100 (CET) Received: from herd.plethora.net (herd.plethora.net [205.166.146.1]) by concorde.inria.fr (8.13.0/8.13.0) with ESMTP id j1CFIoFZ022858 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) for ; Sat, 12 Feb 2005 16:18:51 +0100 Received: from bhurt.plethora.net (bhurt.plethora.net [205.166.146.49]) by herd.plethora.net (8.13.1/8.13.1) with ESMTP id j1CFIUh4008478 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 12 Feb 2005 09:18:33 -0600 (CST) Date: Sat, 12 Feb 2005 09:22:10 -0600 (CST) From: Brian Hurt X-X-Sender: bhurt@localhost.localdomain To: Michael Walter Cc: skaller , Jon , Subject: Re: [Caml-list] The boon of static type checking In-Reply-To: <877e9a17050206221653d14456@mail.gmail.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Miltered: at concorde with ID 420E1E5A.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; caml-list:01 wrote:01 wrote:01 ocamlopt:01 gcc:01 ocaml:01 gcc:01 ocaml:01 intel's:01 compilers:01 imho:01 garbage:01 garbage:01 subsystems:01 applicative:01 X-Spam-Checker-Version: SpamAssassin 3.0.2 (2004-11-16) on yquem.inria.fr X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.0.2 X-Spam-Level: On Mon, 7 Feb 2005, Michael Walter wrote: > On Sun, 6 Feb 2005 23:34:02 -0600 (CST), Brian Hurt wrote: > > Probably a bad idea, but I've got to jump in here. > > > > Full disclosure: I *hate* C++. Mainly because I've actually written real > > programs in it. The next time I have to use C++ in any sort of serious > > way I'm registering c++sucks.com and starting a website to catalog all the > > different ways C++ sucks. Feel free to stop reading at this point. > :-) > > > ... > > > g++ seems to generate better > > > code than ocamlopt for similar simple problems > > > (see Alioth for quantitative evidence given silly > > > set of sample 'problems') > > > > Yep. And, conservatively, 10 times as much effort has gone into the gcc > > optimizer as the Ocaml optimizer. Possibly 100 times. For, according to > > Alioth, about a 10% improvement. It's only with gcc 3.x that C++ managed > > to beat Ocaml on performance. > More effort having gone into gcc and better performance of gcc are > arguments pro gcc, right? ;-) If the 10-30% performance advantage (best case) is the difference between success and failure, then maybe. Of course, going to a professional C/C++ complier like Intel's cc, or IBM's xlc, will buy you another 5-10% over GCC, as they've put maybe 10x more effort into their compilers than has gone into gcc. This is, of course, assuming that a) you are falling into the best case situation, and b) you'd have implemented the same algorithm in both cases, and c) time to implement is irrelevent. Of course, if time to implement really is irrelevent, than going to hand tuned assembly will buy you another 10-30%, generally, and occassionally 2x performance (SSE/Altivec optimizations). > > > > IMHO the single major inefficiency in C++ is also a source > > > of efficiency -- lack of a garbage collector. > > > > It's a source of efficiency on the small scale- it's easy to write a 1,000 > > line program with hand allocation. Rather harder to write a 10,000 line > > program, and a major bitch to write a 100,000 line program without garbage > > collection. > Personally I like it that in C++ you actually have the choice to use > appropriate garbage collection schemes when you desire to do (yep, > multiple kind of GCs for different subsystems/data/... is a win). > Makes it easier with > 1,000,000 line programs :-) Yes! Having a choice means you can fuck it up! And I disbeleive the "makes it easier with large programs" statement. It's contrary to all evidence I've seen, and all my experience. The complexity of a program is, I've postulated, a function of the number of interactions between different parts of the code. And that therefor the innate complexity approximately scales with the square of the number of lines of code- so a 10,000 line program is 100 times as complicated as a 1,000 line program. Brooks has evidence of this as well. So the trick to managing complexity is limiting the interactions (to just the interactions needed). Unexpected/unintended interactions are generally called "bugs". As a side note, this is one of the really nice things about applicative semantics. Now, if there are multiple different "memory management domains", that require different behaviors, you are now introducing new interactions to the program. This is introducing complexity. A classic example of this problem in action. I actually encountered this in real code (of course, this is the distilled example, the real example was spread out over a few tens of thousands of lines of code): #include #include class base { public: virtual char * getName(void) = 0; }; class exA : public base { public: char * getName(void) { return "exA"; } }; class exB : public base { private: char * name; public: exB() { name = new char[4]; strcpy(name, "exB"); } virtual ~exB() { delete[] name; } char * getName(void) { return name; } }; class exC : public base { public: char * getName(void) { char * retval = new char[4]; strcpy(retval, "exC"); return retval; } }; void breakMe(base * ptr) { char * name = ptr->getName(); delete ptr; std::cout << "Object name was \"" << name << "\".\n"; delete[] name; } > > Don't assume that inlining is optimization. Actually, it generally isn't. > > Having actually timed it on modern hardware, a function call costs like > > 2-3 clock cycles these days. Plus 1-2 clock cycles per argument. This is > > compared to the 10-30 clock cycles a mispredicted branch costs, the 20+ > > clock cycles an L1 cache miss/L2 cache hit costs, and the 100-350+ clock > > cycles of an L2 cache miss/memory fetch. > Inlining for very small functions generally is an optimization. Very small functions, yes. But it's less of an optimization than people think, and (especially in C++) it gets way overused. Allowing the programmer to force some functions to be inlined is right up there with allowing the programmer to force some variables to be stored in registers in usefullness. Brian