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

[REBOL] Speeding up code

From: sunandadh::aol::com at: 13-Feb-2002 6:14

I recently tried to put some zip into some sluggish code. I was surprised just how fast a lot of Rebol is. I instrumented several of my suspect functions and found they were almost too fast to meter. The slowest thing I found was (perhaps not surprisingly) Layout. 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? Thanks, Sunanda
>>>>Sample console session:
loop 5 [ unit-timer/start "A code unit" wait (0.001 * random 50) ;; your code here!! unit-timer/start "Another code unit" wait (0.02 * random 20) print unit-timer/end "A code unit" wait (0.1 * random 10) print unit-timer/end "Another code unit" print unit-timer/end "A unit with no start" ] print mold unit-timer/report help unit-timer <snipped>
>>>>>The code:
rebol [] Unit-Timer: func [ {Records elapse time for named units of code Returns:
>> False -- /End called without /Start for same unit >> True -- /Start okay >> decimal -- /End only: cumulative elapse time for unit >> block -- /Report only: history block.
Known problems: 1. Doesn't check for start/end straddling midnight(s) 2. Watch out if you use this in a function -- putting an /End call as the last thing in a function that uses an implicit Return will send the elapse time back to your caller. } /Report {Return units history block Format is: [string time decimal integer ...] (repeats in groups of four) where:
>> string -- is the unit name >> time -- is the latest start time (0 = not being timed) >> decimal -- culmulative elapse time for unit name >> integer -- number of times unit has been timed.
} /Start Unit-name-start [String!] {Start a unit.} /End Unit-name-end [String!] {End a unit.} /local Units-block Unit-data] [ Units-block: [] ;; ------------------------- ;; Handle /Report refinement ;; ------------------------- If Report [Return Units-block] ;; ------------------------ ;; Handle /Start refinement ;; ------------------------ ;; ;; For a new unit, add a history group. ;; If the unit already exists, simply ;; reset its start time. This will lose ;; some elapse time if there was an ;; outstanding /End. if Start [ unit-data: find units-block unit-name-start either none? unit-data [ append units-block compose [(unit-name-start) ;; unit-name (now/time/precise) ;; start time 0.0 ;; cumulative elapse 0 ;; invocations ] ][ poke units-block ;; (re)set start time (1 + index? unit-data) now/time/precise ] Return true ] ; if-start ;; ---------------------- ;; Handle /End refinement ;; ---------------------- unit-data: find units-block unit-name-end if any [none? unit-data decimal? pick units-block (1 + index? unit-data) ] [return false] ;; End without a start poke units-block (2 + index? unit-data) to-decimal (unit-data/3 + (now/time/precise - Unit-data/2)) poke units-block (3 + index? unit-data) unit-data/4 + 1 poke units-block (1 + index? unit-data) 0.0 Return unit-data/3 ;; Return cumulative elapse time for unit ] ; func