| 1 | #!/usr/bin/env Rscript
 | 
| 2 | #
 | 
| 3 | # metrics/native-code.R -- Analyze output of bloaty
 | 
| 4 | #
 | 
| 5 | # Usage:
 | 
| 6 | #   metrics/native-code.R ACTION IN_DIR OUT_DIR
 | 
| 7 | 
 | 
| 8 | library(dplyr)
 | 
| 9 | library(tidyr)  # spread()
 | 
| 10 | library(stringr)
 | 
| 11 | 
 | 
| 12 | source('benchmarks/common.R')
 | 
| 13 | 
 | 
| 14 | options(stringsAsFactors = F,
 | 
| 15 |         # Make the report wide.  tibble.width doesn't appear to do this?
 | 
| 16 |         width=200
 | 
| 17 | )
 | 
| 18 | 
 | 
| 19 | # Categorize names:
 | 
| 20 | # - _doc(__)?
 | 
| 21 | # - PRETTY
 | 
| 22 | # - init?
 | 
| 23 | 
 | 
| 24 | # frame: A table with 3 columns.  ctx$symbols or ctx$compileunits.
 | 
| 25 | Basic = function(frame) {
 | 
| 26 |   ShowValue('Rows: %d', nrow(frame))
 | 
| 27 | 
 | 
| 28 |   frame %>% arrange(desc(filesize)) %>% head(30) -> f1
 | 
| 29 |   ShowFrame('By Size On Disk:', f1)
 | 
| 30 | 
 | 
| 31 |   ShowValue('Total filesize: %d', sum(frame$filesize))
 | 
| 32 | 
 | 
| 33 |   # Number of files
 | 
| 34 |   frame %>% arrange(desc(vmsize)) %>% head(30) -> f2
 | 
| 35 |   ShowFrame('By Size in Virtual Memory:', f2)
 | 
| 36 | 
 | 
| 37 |   ShowValue('Total vmsize: %d', sum(frame$vmsize))
 | 
| 38 | }
 | 
| 39 | 
 | 
| 40 | Report = function(ctx) {
 | 
| 41 |   Banner('Summary of symbols.tsv (from %s):', ctx$opt)
 | 
| 42 |   Basic(ctx$symbols)
 | 
| 43 | 
 | 
| 44 |   Banner('Summary of compileunits.tsv (from %s):', ctx$dbg)
 | 
| 45 |   Basic(ctx$compileunits)
 | 
| 46 | 
 | 
| 47 |   Banner('Other analysis:')
 | 
| 48 | 
 | 
| 49 |   # This isn't foolproof, but docstrings seem to be named with a _doc or
 | 
| 50 |   # __doc__ suffix.
 | 
| 51 |   ctx$symbols %>% filter(str_detect(symbols, '_doc(__)?')) -> f3
 | 
| 52 |   ShowFrame('Big Docstrings (approximate, based on name)', f3 %>% head(20))
 | 
| 53 | 
 | 
| 54 |   ShowValue('%d symbols in %d bytes', nrow(f3), sum(f3$filesize))
 | 
| 55 | }
 | 
| 56 | 
 | 
| 57 | Load = function(in_dir) {
 | 
| 58 |   # 9/2021: read.delim(...) works but somehow read.table(..., sep='\t',
 | 
| 59 |   # header=T) doesn't?
 | 
| 60 |   list(
 | 
| 61 |     symbols = read.delim(file.path(in_dir, 'symbols.tsv')),
 | 
| 62 |     compileunits = read.delim(file.path(in_dir, 'compileunits.tsv'))
 | 
| 63 |   )
 | 
| 64 | }
 | 
| 65 | 
 | 
| 66 | main = function(argv) {
 | 
| 67 |   action = argv[[1]]
 | 
| 68 | 
 | 
| 69 |   if (action == 'metrics') {
 | 
| 70 |     in_dir = argv[[2]]
 | 
| 71 |     ctx = Load(in_dir)
 | 
| 72 | 
 | 
| 73 |     ctx$dbg = argv[[3]]
 | 
| 74 |     ctx$opt = argv[[4]]
 | 
| 75 | 
 | 
| 76 |     Report(ctx)
 | 
| 77 | 
 | 
| 78 |   } else {
 | 
| 79 |     Log("Invalid action '%s'", action)
 | 
| 80 |     quit(status = 1)
 | 
| 81 |   }
 | 
| 82 | }
 | 
| 83 | 
 | 
| 84 | if (length(sys.frames()) == 0) {
 | 
| 85 |   # increase ggplot font size globally
 | 
| 86 |   #theme_set(theme_grey(base_size = 20))
 | 
| 87 |   main(commandArgs(TRUE))
 | 
| 88 | }
 |