home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / lang / pop / 88 < prev    next >
Encoding:
Internet Message Format  |  1992-11-22  |  5.5 KB

  1. Path: sparky!uunet!know!cass.ma02.bull.com!think.com!ames!agate!doc.ic.ac.uk!syma!ianr
  2. From: ianr@syma.sussex.ac.uk (Ian Rogers)
  3. Newsgroups: comp.lang.pop
  4. Subject: Re: Clarity VS Efficiency in POP11
  5. Message-ID: <1992Nov22.131443.11011@syma.sussex.ac.uk>
  6. Date: 22 Nov 92 13:14:43 GMT
  7. References: <TMR.92Nov21122734@emotsun.bham.ac.uk>
  8. Organization: University of Sussex at Brighton
  9. Lines: 160
  10.  
  11. tmr@cs.bham.ac.uk (Tim Read) writes:
  12. > It is my feeling as a competent beginner in POP11, that putting too many
  13. > efficiency hacks into your code tends to lose the inherent clarity that
  14. > POP11 provides.
  15.  
  16. Efficiency *hacks* are bad, sure (Pop11 buys you clarity, a Good
  17. Thing IMHO)
  18.  
  19. > My conclusion is that (bearing in mind I am using an 86 MIP workstation), I
  20. > will not worry about efficiency until I notice that my program is running
  21. > slowly.
  22. > ....
  23. > Until I notice that it takes longer for the program to run than it does for
  24. > the data to be output, I'll lose no sleep over it....
  25.  
  26. But it's this sort of attitude that's brought us dogs like
  27. OpenWindows (I now need a SuperZoom Mega BitBlitter graphics card
  28. with dual carbs, turbo charger and nitrous' laser injection paint
  29. whacker before my xterm can come up within a week :-(
  30.  
  31. > An example of what I mean is using a temporary closure within a
  32. > loop, which looks nice and neat, but will cause extra garbage collections,
  33. > as opposed to using an lblock (As Aaron pointed out).
  34.  
  35. So make a new data type (even notionally) and optimise the code,
  36. *after* you've finished development, by free-listing instances.
  37.  
  38. A case in point:
  39.  
  40. Last week I was developing a graphics package to draw links between
  41. graph nodes. The data structure for the lines are shortvecs of
  42. between 8 and 12 elements. These were being thrown around willy
  43. nilly, but that's ok 'cos I've got a garbage collector.
  44.  
  45. So I set up an animation to demonstrate the links and I keep getting
  46. 1 second pauses. Hmm, garbage collector, bad news in direct
  47. manipulation user interfaces.
  48.  
  49. So I write a free-listing utility:
  50.  
  51.     lconstant
  52.             pvh_len = 12,
  53.             pv_hold = initv(pvh_len),
  54.         ;
  55.  
  56.     define free_pointvec(v);
  57.         lvars   v, i = length(v),
  58.             ;
  59.         returnif(i fi_> pvh_len);
  60.         /***
  61.             we need the second -fast_subscrv- to "persuade" the
  62.             shortvec to act as a full vector
  63.          ***/
  64.         fast_subscrv(i, pv_hold) -> fast_subscrv(1, v);
  65.         v -> fast_subscrv(i, pv_hold);
  66.     enddefine;
  67.  
  68.     define make_pointvec(n);
  69.         lvars   n, v,
  70.             ;
  71.         if n fi_> pvh_len or (fast_subscrv(n, pv_hold) ->> v) == 0 then
  72.             consshortvec(n)
  73.         else
  74.             fast_subscrv(1, v) -> fast_subscrv(n, pv_hold);
  75.             () -> explode(v);
  76.             v
  77.         endif
  78.     enddefine;
  79.  
  80.     constant old_pop_after_gc = pop_after_gc;
  81.  
  82.     /***
  83.         The free-list table will be completely corrupted after a GC
  84.         so we'd better clear it out :-)
  85.      ***/
  86.     define clear_pv_hold;
  87.         set_subvector(0, 1, pv_hold, pvh_len);
  88.         old_pop_after_gc();
  89.     enddefine;
  90.  
  91.     define vars procedure pop_after_gc =
  92.         clear_pv_hold;
  93.     enddefine;
  94.  
  95. Then I change all relevant calls to -consshortvec- with
  96. -make_pointvec-. Easy peasy, and the semantics and the look of the
  97. main body of the code hasn't changed one jot.
  98.  
  99. The optimistations then come in carefully selecting where to place
  100. calls to -free_pointvec-. Purely by coincidence, I'm programming in
  101. the OOP paradigm so no other piece of code gets a look in on these
  102. data structures. There's only one place where the vectors are being
  103. trashed before making a new one. So:
  104.  
  105.     if link.pvec then
  106.         free_pointvec(link.pvec);
  107.         false -> link.pvec; ;;; just to make sure I don't try to use
  108.                             ;;; it later
  109.     endif;
  110.  
  111. This has now completely changed the store usage of my link objects.
  112. In the worst case, a link object will generate one of each size of
  113. vector and then cycle them through the free list.
  114.  
  115. No more pauses in my user interface, Yipeee!! :->
  116.  
  117. I've just realised I haven't answered your implied question. Hmm...
  118.  
  119. In your case you can free-list the closures, either in a simple list
  120. if you're only making closures of a single procedure, or in a
  121. property that matches against the pdpart. I'll tackle the difficult
  122. case (if the weather wasn't so bad I'd be out walking on the South
  123. Downs :( )
  124.  
  125.     define lconstant pdr_table =
  126.         newproperty([], 8, [], "tmpboth")
  127.     enddefine;
  128.  
  129.     define make_closure(n) -> clos;
  130.         lvars   n, i, args, free, clos, pdr,
  131.             ;
  132.         conslist(n) -> args;    ;;; get the rest of the stuff
  133.         () -> pdr;              ;;; from the stack
  134.         pdr_table(pdr) -> free;
  135.         if free == [] then
  136.             ;;; just like before
  137.             partapply(pdr, args) -> clos;
  138.         else
  139.             destpair(free) -> pdr_table(pdr) -> clos;
  140.             1 -> n;
  141.             for i in args do
  142.                 i -> frozval(n, clos);
  143.                 n + 1 -> n;
  144.             endfor;
  145.         endif;
  146.         sys_grbg_list(args);
  147.     enddefine;
  148.  
  149.     define free_closure(clos);
  150.         lvars   clos, pdr = pdpart(clos),
  151.             ;
  152.         clos :: pdr_table(pdr) -> pdr_table(pdr);
  153.     enddefine;
  154.  
  155.     vars a = identfn(% "a", "b" %);
  156.     frozval(1, a) =>
  157.     ** a
  158.  
  159.     vars b = make_closure(identfn, #| "a", "b" |#);
  160.     frozval(1, b) =>
  161.     ** a
  162.  
  163.     free_closure(a);
  164.     vars c = make_closure(identfn, #| "c", "b" |#);
  165.     frozval(1, c) =>
  166.     ** c
  167.  
  168. Ian.
  169.              "Deep in the fundamental heart of mind and Universe,"
  170.            said Slartibartfast, "there is a reason" - Douglas Adams
  171.