It depends on what you mean by "doesn't work."
If you mean setting your timestamp format to contain .x or .xxx and expecting the channel window to show milliseconds in your timestamp instead of x's, then no it doesn't, because that timestamp only recognizes parameters defined for $asctime.
But if you mean using $timestampex in a script then getting the string where your timestamp format is replaced by the milliseconds, then yes it does work.
If you want to use $timestampex without having .xxx showing in your [timestamp], you can change that last line of the alias to not reference $timestampfmt at all, and instead hard-code the string into the alias.
As an aside, when testing this just now, I see that in spite of the script attempting to identify the variance between where $ticks/1000 rolls-over differently than $ctime does, I've found that it doesn't completely eliminate the .nnn number rolling over from .99something to .00something without changing $ctime.
To prevent this completely, your hash table would instead need to hold a long-term constant that's a value that would be added to $ticks to obtain the number of ticks since 1/1/1970. The hashtable constant would be calculated something like:
!hadd misc milliseconds.ticks $~ticks
!hadd misc milliseconds.ticks $calc($~ctime * 1000 - $~ticks)
Then %m would be created like:
var %m $~hget(misc,milliseconds.ticks) + $ticks
You'd then use $left(%m,-3) as a parameter to $asctime in place of $ctime, and use $right(%m,3) in place of the xxx milliseconds. This would be zero-padded already, so wouldn't need to use $base to add the leading zeroes.
This would still have the same milliseconds error as before, occasionally showing the wrong ctime value, but it would never cycle milliseconds past 999 to 000 without displaying the higher ctime time string.