Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: Speeding up code

From: joel:neely:fedex at: 13-Feb-2002 7:36

Hi, Sunanda, [SunandaDH--aol--com] wrote:
> To soup up the code, I wrote an elapse timer function. It's > listed below with some samples of use. Feel free to use it. > > The code is reasonably Rebollish (it uses a persistent local > variable), but I'd appreciate feedback on better ways of > acheiving the same, particularly: > > 1. Can I avoid having to define the same refinement variable > (unit-name) twice (unit-name-start and unit-name-end)? > > 2. Any better suggestions for those awkward Pokes? >
I'd refactor the code to separate the behavior of an individual watch (as an object with its own state) from the behavior of the total collection of watches in existence at a given time (given a just-for-fun name ;-). Watches know how to start, stop, and report their total times (in seconds), while the watchmaker knows how to make a new watch, find a watch by the label placed on it when he made it, and get reports from all of the watches. The code below is fairly minimal, but I think it addresses most of the capabilities you had in UNIT-TIMER (or could be extended easily to include any I missed in a quick read-through). It performs as follows... The watchmaker can create new watches on demand, and a reference to a watch *can* be kept to allow it to be used individually:
>> a: watchmaker/new "frushlinger" >> a/start
== 7:18:24.53
>> b: watchmaker/new "schlocken" >> b/start
== 7:18:38.37
>> c: watchmaker/new "fleegle" >> c/start
== 7:18:58.09 The watchmaker can provide a consolidated report (each watch can return total elapsed time whether running or not):
>> watchmaker/report-all
== ["frushlinger" 46.03 "schlocken" 32.19 "fleegle" 12.47]
>> watchmaker/report-all
== ["frushlinger" 47.95 "schlocken" 34.11 "fleegle" 14.39]
>> watchmaker/report-all
== ["frushlinger" 49.43 "schlocken" 35.59 "fleegle" 15.87] Watches can be individually operated:
>> b/stop
== 46.25
>> watchmaker/report-all
== ["frushlinger" 61.9 "schlocken" 46.25 "fleegle" 28.34]
>> watchmaker/report-all
== ["frushlinger" 63.16 "schlocken" 46.25 "fleegle" 29.6] The watchmaker manages the entire collection, so it's not necessary for watch references to be kept around when not needed -- the watchmaker can find the watch (by label) for later operation:
>> a: b: c: none
== none
>> x: watchmaker/fetch "fleegle" >> x/stop
== 85.96
>> watchmaker/report-all
== ["frushlinger" 125.78 "schlocken" 46.25 "fleegle" 85.96]
>> y: watchmaker/fetch "frushlinger" >> y/stop
== 140.99 The default REPORT-ALL just returns label/time pairs in the order the watches were created. However, the watchmaker can provide the timings in other potentially-useful orders:
>> watchmaker/report-all
== ["frushlinger" 140.99 "schlocken" 46.25 "fleegle" 85.96]
>> watchmaker/report-all/by-label
== ["fleegle" 85.96 "frushlinger" 140.99 "schlocken" 46.25]
>> watchmaker/report-all/by-time
== ["schlocken" 46.25 "fleegle" 85.96 "frushlinger" 140.99] Of course, the result could be processed by something like foreach [lab tot] watchmaker/report-all [ ... ] for whatever purpose... After all that blabbing, here's the code: 8<------------------------------------------------------------ watchmaker: make object! [ collection: [] watch: make object! [ label: "" total: began: ended: 0 reset: func [] [total: began: 0] start: func [] [began: now/time/precise] to-seconds: func [t [time!]] [ t/hour * 60 + t/minute * 60 + t/second ] stop: func [/local ended] [ ended: now/time/precise - began if time? began [ began: 0 total: total + to-seconds ended ] ] report: func [] [ if time? began [stop start] reduce [label total] ] ] reset: func [] [collection: copy []] new: func [lbl [string!]] [ last back insert tail collection make watch [label: lbl] ] fetch: func [lbl [string!]] [ foreach this-watch collection [ if lbl = this-watch/label [return this-watch] ] none ] report-all: func [/by-label /by-time /local rpt] [ rpt: make block! length? collection foreach this-watch collection [ insert tail rpt this-watch/report ] if by-label [sort/skip rpt 2] if by-time [sort/skip/compare rpt 2 2] rpt ] ] 8<------------------------------------------------------------ HTH! -jn- -- ; sub REBOL {}; sub head ($) {@_[0]} REBOL [] # despam: func [e] [replace replace/all e ":" "." "#" "@"] ; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"} print head reverse despam "moc:xedef#yleen:leoj" ;