Created
August 5, 2019 22:10
-
-
Save greggirwin/0305173d962224fbdf59144087b0fe98 to your computer and use it in GitHub Desktop.
Red Load-Time and Type Tally
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Red [ | |
file: %load-time-type-tally.red | |
purpose: { | |
Load a Red file, noting how long it takes to do so, | |
then parse it and tally all the values by datatype. | |
It's not a metric that may prove useful, but in | |
aggregate, we could see what types are most commonly | |
used. | |
I'll correct my own thinking. After just a few sample | |
runs on files, there is a clear pattern in what types | |
appear in sorted order across scripts. This could tell | |
you not only whether a script has a "normal" distribution | |
of types, but could also lead to further analysis of | |
what the focus of some code is, based on its type | |
distribution. | |
} | |
] | |
; from %profile.red | |
delta-time: function [ | |
"Return the time it takes to evaluate a block" | |
code [block! word! function!] "Code to evaluate" | |
/count ct "Eval the code this many times, rather than once" | |
][ | |
ct: any [ct 1] | |
t: now/time/precise | |
if word? :code [code: get code] | |
loop ct [do code] | |
now/time/precise - t | |
] | |
count-type: func [type [word!]][ | |
; Results is a map!. If there's no entry for a type yet, | |
; results/:type returns none, which `+` doesn't like, so | |
; we have to check for that, to prime each entry. | |
either results/:type [ | |
results/:type: results/:type + 1 | |
][results/:type: 1] | |
] | |
;------------------------------------------------------------------------------- | |
; This is where our tally results go | |
results: #() | |
; Main parse rule | |
type-tally-rule: [ | |
some [ | |
; If we see a block coming up, count it, then parse into it, | |
; using this rule | |
ahead block! (count-type 'block!) into type-tally-rule | |
; For any other value, count it by datatype. We use the word | |
; for a type, because maps can't use datatype! values as keys. | |
| set val any-type! (count-type type?/word :val) | |
] | |
] | |
;file-filter: ["Red files" "*.red" "Red System Files" "*.reds" "Rebol Files" "*.r"] | |
file-filter: ["Redbol files" "*.red;*.reds;*.r"] | |
; Keep asking for new files to process, until they don't select one. | |
while [file: request-file/file/filter what-dir file-filter][ | |
load-time: delta-time [blk: load file] ; Track load time | |
clear results ; Self-explanatory | |
parse blk type-tally-rule ; This does all the work | |
print ["File:" mold file "Time to load:" load-time] ; Show top-line info | |
; This is all you really need | |
;print ["Contents:" mold results] ; Show detailed tally results | |
; But if you want to sort the results, you have to conver to a | |
; block, as maps can't be sorted. /skip 2 means treat the block | |
; like key-value pairs. /compare 2 means sort by the second element | |
; (the tally value). /reverse means higher numbers first. | |
res-blk: sort/skip/compare/reverse to block! results 2 2 | |
; One more thing, we want it formatted nicely, but converting | |
; from a map doesn't do that for us. So we'll set our own | |
; new-line markers every 2 elements. | |
new-line/skip res-blk on 2 | |
print ["Contents:" mold res-blk] | |
] | |
; Halt, so the console showing the results doesn't close. | |
halt |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment