Path: utzoo!mnetor!tmsoft!torsqnt!news-server.csri.toronto.edu!cs.utexas.edu!sun-barr!decwrl!adobe!hawley From: hawley@adobe.COM (Steve Hawley) Newsgroups: comp.sys.mac.programmer Subject: Re: Pascal deficiency? Message-ID: <9308@adobe.UUCP> Date: 19 Dec 90 19:46:04 GMT References: <1990Dec17.160242.5095@phri.nyu.edu> <1990Dec17.172613.7941@cs.umn.edu> Reply-To: hawley@adobe.UUCP (Steve Hawley) Organization: Adobe Systems Incorporated, Mountain View Lines: 108 Although this has less to do with Mac programming than programming in general, I remember reading an article about optimization when I was in a compiler class. The gist of the article was that benchmarks the author had done revealed that the code generated by available Pascal compilers was really slow in comparison to that of FORTRAN compilers. The reasoning was that programmers had been using FORTRAN (at that time) for computationally intensive tasks, and out of need, the compilers were tweaked to optimize the living daylights out of the code, whereas nobody bothered using Pascal for "real" tasks, so nobody bothered optimizing the compiler. Vicious circle. It's not completely the case that the language is defficient, but the optimizers were lousy (or non-existent). Of course there are some things the language won't let you do, and the structure of Pascal doesn't help the compiler writer optimize. Autoincrement and autodecrement were not added to C merely as syntactic sugar. They were added in as a concession to the fact that addition and subtraction of small constants are commonplace in programming, and as such we can accomplish several things: 1) Reduce the amount of typing the programmer needs to do. 2) Factor out the special case from the optimizer into the parser. 3) Provide a closer tie to the target machine. 4) Complicate the parser. For example, if I write a routine to copy a string, in C I would do this strcpy(dst, src) char *dst, *src; { while ((*dst++ = *src++) != '\0'); } in Pascal (assuming the same null terminated strings): procedure strcpy(dst, src: ^char); { 'scuse my Pascal, I haven't had to code in it actively for several years } begin while (src^ <> CHR(0)) do begin dst^ := src^; dst := SUCC(dst) src := SUCC(src); end; dst^ := src^ { copy the NULL } end; So what's my point? I don't know, I've kind of lost it. Oh right, I was defending Pascal. Both functions are abstractions of what you want to do: copy data from point a to point b using a sentinel. On a processor with relatively few capabilities, the C version might generate something like this: L0: move src, a0 move (a0), d0 get char add #$1, a0 assuming we can do arithmetic on address registers move a0, src move dst, a0 move d0, (a0) copy char add #$1, a0 move a0, dst cmp #$0, d0 sentinel test bne L0 The Pascal code may generate this: move src, a0 L0: move (a0), d0 cmp #$0, d0 beq L1 move dst, a0 move d0, (a0) add #$1, (a0) move a0, dst move src, a0 add #$1, a0 move a0, src jump L0 L1 move dst, a0 move d0, a0 and lo and behold, the C is a 10 instruction loop, the Pascal an 11 instruction loop. Of course, this isn't a real instruction set and I've purposely limited its capabilities, but how far is it from a RISC processor? Not far. Not far at all. The RISC processor would do most of the work in registers and eliminate a lot of the memory juggling. Of course, withthe Pascal, you must pray that your optimizer has the sense to do good work for you. With a 68000 target processor, there's no reason to get the following assembly language from the C code: move.l src, a0 move.l dst, a1 L0: move.b (a0)+,(a1)+ bne L0 Which you won't get from Think C, by the way, unless you declare your variables to be registers... Whatever. Steve Hawley hawley@adobe.com -- "I'm sick and tired of being told that ordinary decent people are fed up with being sick and tired. I know I'm certainly not, and I'm sick and tired of begin told that I am." -Monty Python