1. there's a bug in that where $ctimems always returns the ctime value for when the variables were initialized

2. If speed is what you are after, you'll want something such as:
Code:
;; Builtin command & identifier calls are forced via ! and ~ respectively. Doing so bypasses script-equivalent lookups

;; same usage as $ctime, and the above $ctimems
alias ctimeex {

  ;; Use hashtables over global variables, can be quite a bit faster
  ;; No need to track $ctime
  ;; $ticks can overflow and roll back to zero, so check for overflow condition
  !if (!$~isid || !$~hget(misc,milliseconds.ticks) == $~null || $~v1 > $~ticks) {
  
    ;; create the hashtable
    !if (!$hget(misc)) hmake misc 1
    
    ;; Use inline arthmatic to avoid the overhead of calling $calc()
    !var %ctime $~ctime + 1
    
    ;; Use $v1 to store $ticks instead of a tracking variable
    !while ($~ctime < %ctime && $~ticks) { !noop }
    
    ;; store the ticks
    !hadd misc milliseconds.ticks $~v1
    
    ;; if used as command, stop processing
    !if (!$~isid) return
  }

  ;; Inline arthmatic to, yet again, avoid the overhead of $calc()
  ;; Done immediately to increase accuracy of the return value
  !var %ms $~ticks - $~hget(misc, milliseconds.ticks), %ms %ms % 1000

  ;; Return ctime with 3 digits of ticks in the decimal position; $calc is avoided
  !return $~+($~ctime, ., $~base(%m,10,10,3))
}

;; Uses the same formatting as $asctime with the addition of the following format items:
;      x: milliseconds as-is, so if the millisecond value is 95ms, x is replaced with "95"
;    xxx: milliseconds padded to 3 places so if the millisecond value is 95ms, xxx is replaced with "095"
alias timestampex {

  ;; existence & overflow check 
  !if ($~hget(misc, milliseconds.ticks) == $null || $v1 > $ticks) { ctimeex }
  
  ;; Immediately calculate the offset
  !var %ms $~ticks - $~hget(misc, milliseconds.ticks), %ms %ms % 1000

  ;; Using $replacexcs so only a single pass is made over the input AND the x/xxx replace matching is case-sensitive
  ;;   Replace xxx with the padded milliseconds
  ;;   Replace x with non-padded milliseconds value
  !return $~replacexcs($~asctime($~ctime, $~timestampfmt), xxx, $~base(%ms, 10, 10, 3), x, %ms)
}



;; initialization events
on *:LOAD:ctimems
on *:START:ctimems



Without comments, blank lines, or verbose var names:
Code:
alias ctimeex {
  !if (!$~isid || !$~hget(misc,milliseconds.ticks) == $~null || $~v1 > $~ticks) {
    !if (!$hget(misc)) hmake misc 1
    !var %c $~ctime + 1
    !while ($~ctime < %c && $~ticks) { !noop }
    !hadd misc milliseconds.ticks $~v1
    !if (!$~isid) !return
  }
  !var %m $~ticks - $~hget(misc,milliseconds.ticks),%m %m % 1000
  !return $~+($~ctime,.,$~base(%m,10,10,3))
}
alias timestampex {
  !if ($~hget(misc,milliseconds.ticks) == $~null || $~v1 > $~ticks) ctimeex
  !var %m $~ticks - $~hget(misc,milliseconds.ticks),%m %m % 1000
  !return $~replacexcs($~asctime($~ctime,$~timestampfmt),xxx,$~base(%m,10,10,3),x,%m)
}
on *:LOAD:ctimeex
on *:START:ctimeex



Note: $ticks is the best that can be done with pure mSL, but by its nature the accuracy can very substantially. I would not suggest using $ticks, or methods involving it if doing anything that requires time precision.

Last edited by FroggieDaFrog; 01/09/17 11:58 AM.

I am SReject
My Stuff