home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / compiler / 1412 < prev    next >
Encoding:
Internet Message Format  |  1992-08-19  |  14.5 KB

  1. Path: sparky!uunet!charon.amdahl.com!pacbell.com!mips!darwin.sura.net!udel!gvls1!faatcrl!iecc!compilers-sender
  2. From: burley@geech.gnu.ai.mit.edu (Craig Burley)
  3. Newsgroups: comp.compilers
  4. Subject: Re: Why is compiled basic slower than C? (Basic is the future)
  5. Keywords: interpreter, performance, design
  6. Message-ID: <92-08-111@comp.compilers>
  7. Date: 18 Aug 92 16:40:56 GMT
  8. References: <92-08-042@comp.compilers> <92-08-095@comp.compilers>
  9. Sender: compilers-sender@iecc.cambridge.ma.us
  10. Reply-To: burley@geech.gnu.ai.mit.edu (Craig Burley)
  11. Organization: Free Software Foundation 545 Tech Square Cambridge, MA 02139
  12. Lines: 254
  13. Approved: compilers@iecc.cambridge.ma.us
  14.  
  15. macrakis@osf.org (Stavros Macrakis) writes:
  16.  
  17.    burley@geech.gnu.ai.mit.edu (Craig Burley) writes:
  18.  
  19.       I think interpreted languages _could_ compile well if _lots_ of effort
  20.       were expended.  However, that kind of effort probably isn't worth it --
  21.  
  22.    Could you please define `interpreted language'?  Is it anything more than
  23.    `a language whose first implementation was interpretive'?  In the present
  24.    discussion, the language under question is Basic, whose first (and only
  25.    for a long time) implementation was in fact compiled.  Other languages you
  26.    might call `interpreted', like Lisp, Prolog, ML, and Snobol, in fact have
  27.    very good compilers, which make major differences in runtime.
  28.  
  29. I was using the apparent prevailing definition of "interpreted language"
  30. which I then subsequently broke down in a few (but not all) ways.  The
  31. prevailing definition, to me, seemed to be "a language I believe is most
  32. often implemented as an interpreter", where "I" is whoever posted the
  33. original question.
  34.  
  35. Meanwhile, as I think I also pointed out in my post, BASIC was indeed
  36. originally a compiled language, and the first implementation I ever used
  37. (and hacked myself) was compiled.  (Note, however, that anyone starting
  38. out using that particular implementation of BASIC would likely assume it
  39. was _interpreted_, and their coding style sometimes changed in obvious
  40. ways once they learned otherwise.  A lot of what I was addressing in my
  41. post had to do with how knowledge of the implementation can govern how
  42. code is written, and this can then affect how easy it is to build a
  43. different implementation that mproves performance for existing code.)
  44.  
  45.       the performance gains compared to the effort, that is -- when contrasted
  46.       to the effort expended in buying new, faster processors, 
  47.  
  48.    The compiler speedup is complementary to the hardware speedup.
  49.  
  50. Agreed.  Memory also is becoming much more plentiful, which generally
  51. improves the ease with which compilers are written more than it does for
  52. interpreters.  Nevertheless, interpreters are still, to varying degrees
  53. for each language, easier to write than compilers.  Most people experience
  54. BASIC as a personal computer implementation, essentially all of which have
  55. been interpreters.  That's probably because building a half-decent
  56. compiler to run on a 4K machine is much harder than building a half-decent
  57. interpreter for that machine.
  58.  
  59.       making the interpreters run faster (often quite easy), 
  60.  
  61.    Interpreters can, of course, be bummed (and often are).  But in many
  62.    cases, this still leaves you far from the compiled speed.
  63.  
  64. Obviously.  But writing the compiler is the trick.  Simply writing _a_
  65. compiler is not enough -- you must write _the_ compiler that produces
  66. output that consistently and greatly exceeds the performance of the
  67. fastest interpreter likely, since the fastest interpreter is probably much
  68. easier to build than even a half-decent compiler, and is probably more
  69. portable.
  70.  
  71.                           translating programs to
  72.       maintenable code in a language designed for compilation, and so on.
  73.  
  74.    This is a possible approach.  However, you lose whatever advantages the
  75.    `interpreted' language had, e.g. more appropriate abstractions, easier
  76.    debugging, fast turnaround, etc.  There are of course compiler-based
  77.    systems that provide easy debugging and fast turnaround e.g. most Lisp
  78.    compilers, but also the CenterLine C (formerly Saber C) system.
  79.  
  80. Yes, but from what little I've seen, people who write code in BASIC rarely
  81. have a problem with the speed of the resulting program.  When they do,
  82. they often are "ready" to move "up" to a language designed for high-speed
  83. execution via compilation, such as C, Pascal, or Fortran, if not Assembly.
  84.  
  85. It would seem to make sense that there would be a large market for a
  86. top-quality compiler for "interpreted languages" (again, languages for
  87. which most users have access only to an interpreted implementation) such
  88. as BASIC, Hypertalk, and so on, and the existence of this market would
  89. cause such a compiler to be built.  As far as I know, such compilers don't
  90. permeate the market the way compilers for C, Pascal, Fortran, or perhaps
  91. even LISP do.  I can't say why that is, except to do the usual "punt to
  92. market forces".
  93.  
  94.       I remember a discussion with rms (GNU EMACS author) regarding TECO, the
  95.       language in which he first wrote EMACS.  TECO was (and still is,
  96.       primarily) an interpreted language (well, it's an editor, kind of like
  97.       the MS-DOS DEBUG program is a partition editor :-).
  98.  
  99.    Teco is a weird language.  Most commands are single-character, and the
  100.    main loop of the interpreter essentially dispatches directly to the
  101.    relevant routine.  So it is a sort of human-readable (well, this is
  102.    debatable, too) byte-compiled form.
  103.  
  104. Obviously it is more human-readable than an object file.  One doesn't have
  105. to worry about endianness.  :-)
  106.  
  107.       He told me about how someone we both knew had developed (or help
  108.       develop) a compiler for TECO and was prepared to demonstrate its
  109.       superiority in benchmarks.  But submitting one simple case
  110.       (something like deleting every other line in the file) proved the
  111.       opposite.
  112.  
  113.    Teco is an extreme case, but even so, you could probably _slightly_ reduce
  114.    runtime by compiling to machine code.  I certainly agree that in most
  115.    cases, it would not be worthwhile to try to compile Teco code....
  116.  
  117. Right, and this makes the likelihood of being able to fund development of
  118. a top-quality compiler for TECO more difficult.  However, it is
  119. technically feasible, probably roughly as feasible as doing a top-quality
  120. BASIC compiler.
  121.  
  122. Remember, the original question was "why is compiled BASIC slower than
  123. [compiled] C?"  I'm saying the answer has a lot to do with the fact that
  124. there doesn't seem to be enough of a market for a top-quality BASIC
  125. compiler that might be able to challenge the superiority of C compilers.
  126. On the other hand, an OOP BASIC compiler might be able to make a good run
  127. at most C++ implementations.
  128.  
  129.          (Of course, TECO is probably like APL in that the time
  130.       it takes to read in source code and figure out what it means is
  131.       minimal, as compared to C, FORTRAN, and COBOL.  So the penalty for
  132.       being an interpreter could be seen as significantly lower for terse
  133.       languages like TECO and APL,
  134.  
  135.    Teco is not just terse, it requires no lexing or parsing.  Like APL, many
  136.    of its operators are bulk operators and so most runtime is within their
  137.    inner loops.  But even APL has been compiled with good results....
  138.  
  139. Yes, and even TECO, BASIC, and all other languages _can_ be compiled with
  140. excellent results, perhaps even superior to what can be achieved via
  141. translation to C.  I know, for instance, that a lot of Fortran code cannot
  142. be translated to C without losing some speed (unless the compilers
  143. globally optimize entire programs) and without using extensions to the
  144. language that I've rarely seen implemented.
  145.  
  146. The question is, why aren't there lots of great compilers for BASIC?  The
  147. answer seems to be "because there aren't lots of people demanding them".
  148.  
  149.       ...There is another major issue regarding interpretation which puts
  150.       both BASIC and C in the "compiled" camp: whether the running
  151.       program has a means to modify itself at run time.  LISP, for
  152.       example, belongs in the "interpreted" camp.
  153.  
  154.    This is not really a problem.  The amount of Lisp code which actually
  155.    modifies the program written by the programmer is just minuscule.  Much
  156.    more code _generates_ pieces of Lisp, typically using the `macro' feature.
  157.    But almost all cases of macro usage are handled straightforwardly in Lisp
  158.    compilers.  There are a few cases where Lisp code generates code on the
  159.    fly, then executes it.  This is handled by having an interpreter loaded
  160.    along with the compiled code, and assuring that code can work correctly in
  161.    such a mixed environment.  In fact, most Lisp implementations _assume_ a
  162.    mixed environment....
  163.  
  164. I don't feel it is a _problem_, but it is, I think, a more important
  165. _issue_ in defining what constitutes an _interpreted_ vs. _compiled_
  166. language.  Ideally, one might say a compiled language is one where all the
  167. facilities needed by a program written in that language are identifiable
  168. by analyzing the source program; an interpreted language is one where all
  169. the facilities are available to the running program at all times.  By
  170. "facilities" I mean things like library routines, language constructs, I/O
  171. capabilities, and so on.
  172.  
  173. By this definition, for existence, one could say IBM's JCL is a fairly
  174. pure compiled language, at least as well as I understood it way back when.
  175. Your source program had to identify _all_ the input and output files (data
  176. sets) explicitly -- no runtime determination of which file to open and when
  177. to open it.  This seems artificially constraining, but it's really great
  178. for some things that are "meta-language" issues, like scheduling of tasks
  179. (you don't get "deadly embrace" in an environment where multiple JCL jobs
  180. run at the same time like you might in a traditional interactive-shell-
  181. script-as-batch-job environment).
  182.  
  183. On the other hand, LISP is a fairly pure interpreted language, since,
  184. while running, a program can read in or otherwise construct an entirely
  185. new program and run that.  It also can examine and modify itself as
  186. needed.
  187.  
  188. Fortran and C lean more toward the compiled side, Fortran-77 more so since
  189. its memory needs are statically determinable without global
  190. interprocedural analysis.  But they both offer the ability to dynamically
  191. determine names of files to be opened and closed, and both offer dynamic
  192. determination of formatting for strings.  Hence, any Fortran or C program
  193. that uses a run-time format or printf-type string, especially if that
  194. run-time string is pulled from an input stream, the compiler must ensure
  195. that _all_ facilities accessible via that mechanism are available at run
  196. time.
  197.  
  198. In some ways, BASIC is even more of a compiled language than Fortran and
  199. C.  (However, this is based on awfully old and probably faulty knowledge
  200. of the full scope of the language.)  I don't recall that it has anything
  201. quite like _run-time_ formatting of strings.  On the other hand, its
  202. memory needs, unlike Fortran, are not statically determinable.  (The
  203. implementation I started out with just let arrays, even string arrays,
  204. grow as much as needed, like C can do via malloc.)
  205.  
  206. Of course, a big determinant of how easy it is to build a compiler that
  207. produces excellent code is how extensive the built-in type mechanism is
  208. and how much it is used.  C and even Fortran are pretty well endowed in
  209. this respect because they offer a fair number of frequently useful types
  210. and programmers tend to use those types appropriately.  LISP, Smalltalk,
  211. and BASIC, to varying degrees, offer less of some types (varying kinds of
  212. integers and floats) and more of others (varying-length strings, dynamic
  213. and/or sparse arrays), and programmers in those languages might not always
  214. be as careful to use the most restrictive type minimally necessary to get
  215. the job done as they are with Fortran and C.  So, the compiler's job must
  216. include the ability to determine, in place of the programmer, what more
  217. restricted type can be gotten away with to produce more efficient code.  C
  218. and Fortran compilers generally don't have to do this to do what is widely
  219. considered to be a good job of compilation.  A good BASIC compiler
  220. probably would.
  221.  
  222. Practically speaking, lots of what makes a compiler or interpreter hard or
  223. easy to implement is not so much the theoretical things as the practical.
  224. C programmers have long designed and implemented code with the idea that
  225. memory is basically flat, pointers can be passed around freely, and so on.
  226. A C interpreter would have to deal with things like how to do ioctl() or
  227. other things where it might need to determine how the programmer expected
  228. memory to be laid out.  That might be easy or hard depending on how the
  229. interpreter is designed and what other problems it is solving.  A Fortran
  230. interpreter that executes as it reads code without first reading the
  231. entire procedure can't be built anyway, since a DATA statement that
  232. specifies initial values for variables can be at the end of a procedure.
  233. BASIC, on the other hand, ws pretty much designed for this kind of
  234. execution, from what I can remember -- it didn't, years ago, even have to
  235. worry about "separately compiled modules" (where the initial value for a
  236. global variable used by, say, the main program is contained in some other
  237. file or procedure).
  238.  
  239. And it's actually easier in some ways to build a compiler for a structured
  240. language, as far as how to handle a GOTO from one block to another, as in:
  241.  
  242. ... { ... goto foo;  ... }
  243.  
  244. ... { ... { ... { ... foo: ... } ... } ... } ...
  245.  
  246. The compiler of code like this in ANSI C or Fortran-77 has much less to
  247. worry about than a canonical interpreter, the latter having to worry about
  248. playing around with stacked blocks and so on.  This may seem obvious to
  249. most of the readers here, but 've seen at least one implementation of an
  250. interpreter where the designer seemed to have forgotten about cases like
  251. this (it was for a shell language much like PL/I), or at least the code
  252. didn't handle it right.
  253.  
  254. Ultimately, interpreters and compilers seem to be one of those areas in
  255. which theory is fine, but practice is what governs both perceptions and
  256. realities.  There don't seem to be adequate definitions of terms (but then
  257. I'm no theorist) nor summaries of key language facilities that distinguish
  258. between the various languages described (to which could be usefully added
  259. and researched: Forth, MUMPS, Eiffel, ADA...).  I wonder how hard or easy
  260. (or useful) it would be to design a language that had facilities that met
  261. today's and tomorrow's projected needs, yet lent itself well to pure
  262. interpretation, pure global compilation, and other flavors in between the
  263. extremes?
  264. --
  265. James Craig Burley, Software Craftsperson    burley@gnu.ai.mit.edu
  266. -- 
  267. Send compilers articles to compilers@iecc.cambridge.ma.us or
  268. {ima | spdcc | world}!iecc!compilers.  Meta-mail to compilers-request.
  269.