matthews@harvard.UUCP (Jim Matthews) (04/09/86)
There have been a couple of postings about the new LightspeedC compiler, and since I recently ported a large (2200 line) program from Aztec to that environment, I figured that the net might be interested in my reaction. I had been using Aztec for about a year, and my familiarity with Unix-style utilities and the speed of the Aztec compiler made me very satisfied. One week of Lightspeed has convinced me to switch: the environment is superior, both in design and execution, and the compiler brings new meaning to the word "fast." I have some benchmarks below, but they only tell part of the story. The best part of Lightspeed is its "feel" -- a whole range of features make it effortless to use and seemingly even faster than the numbers would indicate. Environment =========== Lightspeed is one big application, about 170k on the disk, and requires 512k to run. The compiler deals with programming tasks using a data structure called the project. Projects are basically lists of source files and libraries included in the program. A window with the names of these files is always on the screen. The visual representation of the project makes some tasks more natural, as well as fast. The segmentation, if any, of the program is represented by the grouping of the names in the window: to change it you just drag them around. This is much nicer than long linker commands. To edit a source file you just double-click on a name -- avoiding both the typing of Aztec and the SFGetFile dialog of other systems. The project also contains the object code produced by compiles (so no .o files) and other information to speed development. Make dependencies are generated automatically, i.e. it checks source files for #includes and keeps track of when you change what. This isn't as powerful as Unix make, but it's good enough for most tasks and best of all, it's totally transparent. One cost of using the project format is disk space: the project file for my 76k program totaled over 200k; by contrast, the .o files produced by Aztec for the same program totaled 86k. The editor is included in the single application: it is comparable to MDS Edit, with the one significant plus of multi-file search. This eliminates much, though not all, of the need for grep. The integration between the compiler and editor is very close. When the compiler finds an error, you are popped into the editor at the line of the error. Compiling open files takes into account changes since your last save and the Make utility marks the file as not compiled if you then quit without saving changes. The editor is quick with scrolling, does not mess up with large cuts and pastes, and handles at least a dozen open files. The one drawback to the close integration of the system is that you could not easily use another editor if you wanted. Fortunately, the included editor is good enough to diminish that problem. Programs under development can be run from within Lightspeed, through some sort of executive. The program run is real machine code, and runs as fast as a stand-alone version, but when you quit you return to Lightspeed with your project still open. To build a stand-alone application file takes a little while (for my program, 1 minute), and yields a standard Mac application. Speed ===== Think is really pushing the speed of the compiler, and rightly so: while not quite as impressive as those advertised by Think (reasons below), my benchmark figures essentially confirm the hype. Here's what I got compiling a 2200 line program, broken into 16 source files: Configuration: 1Mbyte Mac Plus, with one 800k disk drive and one 300k Ram disk. In both cases, all system files, source, and libraries were on the floppy, include files and the compiler/editor/linker were on the ram disk. Times are in seconds, turnaround refers to the time necessary to recompile, link, and run the program after changing one typical source file. Aztec ver. 1.06g LighspeedC Beta compile all files: 1320 550 link/run: 127 26 turnaround: 258 76 code size in bytes: 70792 76860 This benchmark may or may not be typical. I believe that on a hard disk system, or if the source and project files were on ram-disks, Lightspeed's edge in compile speed would be even greater. Most of the time cited above was spent reading source and writing output to a slow floppy: the actual compilation is over 250 lines/second (as displayed by their line counter). Think claims that it takes 2 minutes to recompile Lightspeed in itself (1 Mbyte source) on ram disks, and I believe it. On the other hand, using faster io devices would help Aztec in the link comparison, since Lightspeed links in ram (for my program, in 1.5 seconds!). As for code size, I think that the difference may be due to Lightspeed linking in more stdio code than I need: I'll look into that when I get the release version with source for libraries. So how does Lightspeed do it? There are a number of reasons. Since it's one program, it doesn't have to repeatedly load the compiler. Most of the linking is taken care of at compile time (the project document makes a global symbol table possible) and libraries are linked only when you add them to the project, not at every make (which makes sense, as they probably didn't change). The compiler does everything in ram, with no temp files, and I'm sure that helps a lot. Also, there is no cascading error recovery-- the first error sends you back to the editor -- although I don't think that won them a lot of speed. On the other hand, the compiler checks for the number of arguments to toolbox calls, does all the pre-linking, and still beats Aztec hands down. So it's very fast, but they seem to have made it fast the old-fashioned way: painstaking optimization. The best thing about Lightspeed's speed is the way it changes your work habits. With Aztec I was loath to recompile the program with just a single change, and having to alter a global include file (and thus trigger re-compilation of every source file) was a prospect to be met with dread. Lightspeed makes it easy to make small changes and then see what happens. There's even a "Check Syntax" option that rivals the speed of an interpreter (since it doesn't write output) making it easy to check your work during a long type-in session. Bugs ==== Alas, there are always bugs. One that I found is particularly insidious for programs using floating-point, and apparently was not fixed before shipping. An error in the way casted expressions are processed results in the following: #define CONSTANT any-integer int foo; if ((double)foo == (double)(foo-CONSTANT)) printf("Bug!"); printing out a message. The bug manifests itself with implicit casts also -- x/foo evaluates to the same thing as x/(foo-CONSTANT), where x is a double. This bug is serious, and Think was very attentive when I called it in. A week later, however, I called back and it hadn't been fixed; meanwhile the compiler is shipping. Anyone contemplating using Lightspeed for floating point should be aware of the problem, and perhaps wait for an update. The work-around is to cast the int to a double before the arithmetic, a small loss in performance and a large loss in programmer convenience. I'm still looking for the last occurances of such expressions in my code. Portability =========== Lightspeed handles standard K&R C, with the following differences/ features of note: Structure passing by values Argument # checking on toolbox calls No inline assembly -- must link in assembler output separately "pascal" keyword for pascal-style routines (just like Aztec) Explicit string conversion with CtoPstr and PtoCstr (like Aztec) 16 bit ints, 32 bit longs and floats, 80 bit doubles (uses SANE) I ported my program in two evenings with occasional glances at the documentation, all the while learning how to use the Lightspeed system. The biggest hassles were renaming include files and dealing with points. Aztec provides a macro to pass points to LineTo and MoveTo (for example) by casting them to a long. Since Lightspeed checks number of arguments, it had to be replaced with a macro that separates a point into its structure elements. The documentation is written toward users of other Mac C compilers (Consulair, Megamax, and Aztec) and points out many of the differences. All in all, the manual looks good although I didn't need to look at it much. All in all, I think that Lightspeed is simultaneously the cheapest and best Mac C compiler available. Think has to fix the floating point bug, and it would be nice if they provided a means of converting project files to other formats (there is an MDS => Lightspeed conversion utility) but otherwise it looks great. If the advertised Quicksilver Pascal compiler uses the same technology, Apple's Workshop could have serious competition before it's even released. Jim Matthews matthews@harvard The above views are mine, and may or may not reflect those of my employer and Harvard University. I'm sure that LightspeedC and Quicksilver are trademarks of Think Technologies, that Aztec is a trademark of Manx Software, and that MDS is a trademark of Apple Computer Corporation.
db@cbosgd.UUCP (J. Muir) (04/10/86)
In article <848@harvard.UUCP> matthews@harvard.UUCP (Jim Matthews) writes: > > There have been a couple of postings about the new LightspeedC >compiler, and since I recently ported a large (2200 line) program from >Aztec to that environment, I figured that the net might be interested in >my reaction. > : >To edit a source file you >just double-click on a name -- avoiding both the typing of Aztec and the >SFGetFile dialog of other systems. Minor point, but: Aztec 1.06g (which the author later mentions using for his comparisions) has the "compromise" menu-bar/command-line user interface in its shell. If the current directory has any .c files in it, you get Source and Compile menus added to the bar. You can then put a check next to the source file of interest and edit, compile, assemble, link, and/or execute by simply selecting the appropriate item on the Compile menu. There are also Compile options for automatic sequences. This is much nicer than having to type commands to the shell (especially without a history mechanism) but it's a little bizarre to watch. This scheme works best for relatively small applications consisting of a single source file. If you need link options you can set them once using the LFLAGS environment variable. Similarly, I set the environment so the edit item uses the name "vi" for the editor (Z so renamed to avoid typing frustrations; you can use that to get MDS Edit or whatever editor you use). I believe FLAGS variables also exist for the compiler and assembler. For larger applications, you'd want to use the Aztec make facility, which I haven't used myself because I haven't written any large applications, nor am I anxious to plunge into makefile-writing (I sure hope New Make catches on and Macintosh C packages pick up its makefile style). Dave Bursik/..cbosgd!db