Path: utzoo!utgpu!news-server.csri.toronto.edu!clyde.concordia.ca!uunet!tut.cis.ohio-state.edu!ucbvax!MITCH.ENG.SUN.COM!wmb From: wmb@MITCH.ENG.SUN.COM Newsgroups: comp.lang.forth Subject: Procedure call overhead Message-ID: <9003230003.AA15895@jade.berkeley.edu> Date: 22 Mar 90 02:18:04 GMT Sender: daemon@ucbvax.BERKELEY.EDU Reply-To: wmb@MITCH.ENG.SUN.COM Organization: The Internet Lines: 94 > I may regret asking this, but here goes. I notice that in > many comp.lang.forth postings there is a distinct tendency > to criticise other languages because of procedure call > overhead. Now I would be the first to agree that overhead > is to be avoided where possible, but is it not taking things > a little too far to say C is too slow? If that's how you > feel about C, what do you have to say about Pascal, or Ada? I think a lot of Forth programmers have this "urban myth" notion that C procedure calls are horribly slow and the Forth procedure calls are blazing fast. It ain't so. On most RISC processors, procedure calls are blazing fast. Even on CISC processors, they aren't slow. You have do do some pushing and popping, but not an execessive amount. In most applications, procedure call overhead rarely amounts to a significant overall cost. People seem to use efficiency arguments to justify the writing of long procedures. In most cases, I believe those arguments are specious. I believe that the *syntactic* overhead of *coding* C procedure calls is the most significant impediment to factoring C procedures into small chunks. To create a new C procedure, you need to declare variables and stuff; this is just enough trouble to keep a lot of people from doing it routinely. The syntactic overhead of a typical 2-input, 1-output procedure is: int doit(foo,bar) int foo; int bar; { ; return(); } This is even worse if instead of "int"s, you want the arguments to be of type "register struct mumble *". In Forth, you would instead have: : doit ( foo bar -- result ) ; Admittedly, people *ought* to be willing to pay the syntactic price (i.e. go to the effort) of creating a new procedure, but they usually aren't, especially when they can rationalize not doing so on "efficiency" grounds. There are some interesting quantum effects in human nature. It doesn't have to be a lot of trouble; "just a little too much" has the same effect. I think maybe Forth programmers have a particularly low tolerance for boilerplate, even when it is really and truly useful or even necessary. I have seen this attitude while trying to convince Forth people of the necessity of certain second-order interface functions in proposed extension packages. The interesting thing is, new Forth programmers tend to write long procedures too. Then, if somebody yells at them or twists their arm for long enough, they will eventually start to use shorter and shorter procedures, and then they are convinced. When they go back to programming in another language (e.g. C), the short procedure style will carry over, and they will be more willing to pay the syntactic price. Having said all this, I have to admit that, if you look at the C source code for my C Forth 83 product, you will see one excruciatingly long procedure in the midst of a collection of reasonably-sized ones. I justify this on (are you ready?) efficiency grounds. It turns out that, in the particular case of trying to implement Forth in C, the procedure call overhead really does matter. However, I claim that this is an unusual case, because most Forth primitives do so *very* little work, and there isn't much code over which to amortize the overhead. Actually, it's not only the procedure call overhead that is the reason for the big procedure in C Forth, it's also the inability to declare global "register" variables, meaning that you would otherwise have to keep the data stack pointer, interpreter pointer, and return stack pointer in memory. (Lest anybody think that I'm criticising C for not allowing global "register" variables, I would like to point out that there are excellent reasons for this restriction. I leave the reasoning as an exercise for the reader, with the following hint: consider that C modules may be separately compiled and later linked together). Thus ends a long-winded answer to an excellent question. Mitch Bradley