aboutsummaryrefslogtreecommitdiff
path: root/generator/node_modules/xmlbuilder/perf/index.coffee
blob: 3bd0f931711b624e546349a350d8ac5cf6d514f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
builder = require('../src/index')
git = require('git-state')
fs = require('fs')
path = require('path')
{ performance, PerformanceObserver } = require('perf_hooks')

global.xml = builder.create
global.doc = builder.begin

global.perf = (description, count, func) ->

  totalTime = 0

  callback = (userFunction) ->
    startTime = performance.now()
    for i in [1..count]
      userFunction()
    endTime = performance.now()
    totalTime += endTime - startTime
  func(callback)

  averageTime = totalTime / count

  version = require('../package.json').version
  working = gitWorking(gitDir)
  if working then version = version + "*"
  if not perfObj[version] then perfObj[version] = { }

  perfObj[version][description] = averageTime.toFixed(4)

readPerf = (filename) ->
  if not fs.existsSync(filename) then fs.closeSync(fs.openSync(filename, 'w'))
  str = fs.readFileSync(filename, 'utf8')
  if str then JSON.parse(str) else { }

runPerf = (dirPath) ->
  for file from walkDir(dirPath)
    filename = path.basename(file)
    if filename is "index.coffee" or filename is "perf.list" then continue
    require(file)

walkDir = (dirPath) ->
  for file in fs.readdirSync(dirPath)
    filePath = path.join(dirPath, file)
    stat = fs.statSync(filePath)
    if stat.isFile() then yield filePath else if stat.isDirectory() then yield from walkDir(filePath)
  return undefined

gitWorking = (dirPath) ->
  return git.isGitSync(dirPath) and git.dirtySync(dirPath)

printPerf = (perfObj) ->
  sorted = sortByVersion(perfObj)

  for sortedItems in sorted
    version = sortedItems.version
    items = sortedItems.item
    sortedItem = sortByDesc(items)

    if parseVersion(version)[3]
      console.log "\x1b[4mv%s (Working Tree):\x1b[0m", version
    else
      console.log "\x1b[4mv%s:\x1b[0m", version

    longestDescription = 0
    for item in sortedItem
      descriptionLength = item.description.length
      if descriptionLength > longestDescription 
        longestDescription = descriptionLength

    for item in sortedItem
      description = item.description
      averageTime = item.averageTime
      prevItem = findPrevPerf(sorted, version, description)
      if prevItem
        if averageTime < prevItem.item[description]
          console.log "  - \x1b[36m%s\x1b[0m \x1b[1m\x1b[32m%s\x1b[0m ms (v%s was \x1b[1m%s\x1b[0m ms, -\x1b[1m%s\x1b[0m%)", padRight(description, longestDescription), averageTime, prevItem.version, prevItem.item[description], (-100*(averageTime - prevItem.item[description]) / prevItem.item[description]).toFixed(0)
        else if averageTime > prevItem.item[description]
          console.log "  - \x1b[36m%s\x1b[0m \x1b[1m\x1b[31m%s\x1b[0m ms (v%s was \x1b[1m%s\x1b[0m ms, +\x1b[1m%s\x1b[0m%)", padRight(description, longestDescription), averageTime, prevItem.version, prevItem.item[description], (100*(averageTime - prevItem.item[description]) / prevItem.item[description]).toFixed(0)
        else
          console.log "  - \x1b[36m%s\x1b[0m \x1b[1m%s\x1b[0m ms (v%s was \x1b[1m%s\x1b[0m ms,  \x1b[1m%s\x1b[0m%)", padRight(description, longestDescription), averageTime, prevItem.version, prevItem.item[description], (100*(averageTime - prevItem.item[description]) / prevItem.item[description]).toFixed(0)
      else
        console.log "  - \x1b[36m%s\x1b[0m \x1b[1m%s\x1b[0m ms (no previous result)", padRight(description, longestDescription), averageTime

padRight = (str, len) ->
  str + " ".repeat(len - str.length)

writePerf = (filename, perfObj) ->
  writePerfObj = { }
  for version, items of perfObj
    if not parseVersion(version)[3]
      writePerfObj[version] = items
  fs.writeFileSync(filename, JSON.stringify(writePerfObj, null, 2) , 'utf-8')

findPrevPerf = (sorted, version, description) ->
  prev = undefined
  for item in sorted
    if compareVersion(item.version, version) is -1
      if item.item[description]
        prev = item
  return prev

sortByVersion = (perfObj) ->
  sorted = []
  for version, items of perfObj
    sorted.push
      version: version
      item: items
  sorted.sort (item1, item2) ->
    compareVersion(item1.version, item2.version)

sortByDesc = (item) ->
  sorted = []
  for description, averageTime of item
    sorted.push
      description: description
      averageTime: averageTime
  sorted.sort (item1, item2) ->
    if item1.description < item2.description then -1 else 1

parseVersion = (version) ->
  isDirty = version[version.length - 1] is "*"
  if isDirty then version = version.substr(0, version.length - 1)
  v = version.split('.')
  v.push(isDirty)
  return v

compareVersion = (v1, v2) ->
  v1 = parseVersion(v1)
  v2 = parseVersion(v2)

  if v1[0] < v2[0]
    -1
  else if v1[0] > v2[0]
    1
  else # v1[0] = v2[0]
    if v1[1] < v2[1]
      -1
    else if v1[1] > v2[1]
      1
    else # v1[1] = v2[1]
      if v1[2] < v2[2]
        -1
      else if v1[2] > v2[2]
        1
      else # v1[2] = v2[2]
        if v1[3] and not v2[3]
          1
        else if v2[3] and not v1[3]
          -1
        else
          0


perfDir = __dirname
gitDir = path.resolve(__dirname, '..')
perfFile = path.join(perfDir, './perf.list')
perfObj = readPerf(perfFile)
runPerf(perfDir)
printPerf(perfObj)
writePerf(perfFile, perfObj)