@browserless/benchmark 9.3.14 → 9.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/package.json +6 -7
  2. package/src/cpu.js +2 -2
  3. package/src/index.js +83 -35
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@browserless/benchmark",
3
3
  "description": "Benchmarking tool for testing different browserless configurations",
4
4
  "homepage": "https://browserless.js.org/#/?id=benchmark",
5
- "version": "9.3.14",
5
+ "version": "9.6.2",
6
6
  "main": "src/index.js",
7
7
  "author": {
8
8
  "email": "josefrancisco.verdu@gmail.com",
@@ -32,14 +32,13 @@
32
32
  "asciichart": "latest",
33
33
  "browserless": "latest",
34
34
  "debug-logfmt": "latest",
35
- "fmt-obj": "latest",
36
- "lodash": "latest",
37
35
  "measured": "latest",
38
- "meow": "latest",
36
+ "meow": "9",
39
37
  "nanobench": "latest",
40
- "p-all": "latest",
38
+ "p-all": "3",
41
39
  "percentile": "latest",
42
- "pretty-ms": "latest",
40
+ "picocolors": "latest",
41
+ "pretty-ms": "7",
43
42
  "process-stats": "latest",
44
43
  "puppeteer": "latest",
45
44
  "puppeteer-firefox": "latest",
@@ -58,5 +57,5 @@
58
57
  "test": "exit 0"
59
58
  },
60
59
  "license": "MIT",
61
- "gitHead": "ab94c2a550d86631218340efe7864eee38d2c37e"
60
+ "gitHead": "e29ac9d5b86e7db27429130abc9689bbf39025dd"
62
61
  }
package/src/cpu.js CHANGED
@@ -3,11 +3,11 @@
3
3
  const sieveOfErathosthenes = require('sieve-of-eratosthenes')
4
4
  const bench = require('nanobench')
5
5
 
6
- const N = process.argv[2] || 1000
6
+ const N = Number(process.argv[2]) || 10
7
7
 
8
8
  const ITERATIONS = [...Array(N).keys()]
9
9
 
10
- bench('calculate a sieve value', async function (b) {
10
+ bench('calculate a sieve value', b => {
11
11
  b.start()
12
12
  ITERATIONS.forEach(() => sieveOfErathosthenes(33554432))
13
13
  b.end()
package/src/index.js CHANGED
@@ -1,13 +1,10 @@
1
1
  'use strict'
2
2
 
3
- process.setMaxListeners(Infinity)
4
-
5
3
  const createBrowserless = require('browserless')
6
- const { includes, reduce } = require('lodash')
7
4
  const processStats = require('process-stats')
8
5
  const asciichart = require('asciichart')
6
+ const { gray } = require('picocolors')
9
7
  const prettyMs = require('pretty-ms')
10
- const prettyObj = require('fmt-obj')
11
8
  const Measured = require('measured')
12
9
  const pAll = require('p-all')
13
10
  const meow = require('meow')
@@ -32,6 +29,10 @@ const cli = meow(
32
29
  method: {
33
30
  type: 'string'
34
31
  },
32
+ strategy: {
33
+ type: 'string',
34
+ default: 'context'
35
+ },
35
36
  pool: {
36
37
  type: 'boolean',
37
38
  default: false
@@ -52,27 +53,68 @@ const cli = meow(
52
53
  }
53
54
  )
54
55
 
55
- const benchmark = async ({ createBrowserless, method, url, opts, iterations, concurrency }) => {
56
+ const getStrategy = opts => {
57
+ return {
58
+ context: () => {
59
+ return {
60
+ onInit: () => createBrowserless(opts),
61
+ onCreate: browserlessFactory => browserlessFactory.createContext(),
62
+ onDestroy: browserless => browserless.destroyContext(),
63
+ onClose: browserlessFactory => browserlessFactory.close()
64
+ }
65
+ },
66
+ process: () => {
67
+ const browsers = new Map()
68
+ return {
69
+ onInit: () => {},
70
+ onCreate: (_, n) => {
71
+ const browserlessFactory = createBrowserless(opts)
72
+ browsers.set(n, browserlessFactory)
73
+ return browserlessFactory.createContext()
74
+ },
75
+ onDestroy: async (browserless, n) => {
76
+ const browserlessFactory = browsers.get(n)
77
+ await browserless.destroyContext()
78
+ return browserlessFactory.close()
79
+ },
80
+ onClose: () => {}
81
+ }
82
+ }
83
+ }
84
+ }
85
+
86
+ const benchmark = async ({
87
+ strategy,
88
+ browserlessFactory,
89
+ concurrency,
90
+ getStats,
91
+ iterations,
92
+ method,
93
+ opts,
94
+ url
95
+ }) => {
56
96
  const timer = new Measured.Timer()
57
97
  const promises = [...Array(iterations).keys()].map(n => {
58
98
  return async () => {
59
99
  const stopwatch = timer.start()
60
- const browserless = await createBrowserless()
100
+
101
+ const browserless = await strategy.onCreate(browserlessFactory, n)
61
102
  await browserless[method](url, opts)
62
- await browserless.close()
103
+ await strategy.onDestroy(browserless, n)
63
104
  const time = stopwatch.end()
64
- const stats = processStats()
105
+ const { cpu, delay, memUsed } = getStats()
65
106
 
66
107
  console.log(
67
- `n=${n} cpu=${stats.cpu} mem=${stats.memUsed.pretty} eventLoop=${
68
- stats.delay.pretty
69
- } time=${prettyMs(time)}`
108
+ ` #${n < 10 ? `0${n}` : n} ${gray(
109
+ `cpu=${cpu.pretty} mem=${memUsed.pretty} eventLoop=${delay.pretty} time=`
110
+ )}${prettyMs(time)}`
70
111
  )
71
112
  return time
72
113
  }
73
114
  })
74
115
 
75
116
  const times = await pAll(promises, { concurrency })
117
+ await getStats.destroy()
76
118
  const histogram = timer.toJSON().histogram
77
119
  return { times, histogram }
78
120
  }
@@ -81,45 +123,51 @@ const main = async () => {
81
123
  const [url] = cli.input
82
124
  if (!url) throw new TypeError('Need to provide an URL as target.')
83
125
 
84
- const {
85
- method,
86
- concurrency,
87
- pool: isPool,
88
- poolMin,
89
- poolMax,
90
- iterations,
91
- firefox,
92
- ...opts
93
- } = cli.flags
126
+ const { method, concurrency, iterations, firefox, ...opts } = cli.flags
94
127
 
95
128
  if (!method) throw new TypeError('Need to provide a method to run.')
96
129
 
97
130
  const puppeteer = firefox ? require('puppeteer-firefox') : require('puppeteer')
98
131
 
132
+ const strategy = getStrategy({ puppeteer, ...opts })[cli.flags.strategy]()
133
+ const getStats = processStats()
134
+ const browserlessFactory = strategy.onInit()
135
+
136
+ console.log()
99
137
  const { times, histogram } = await benchmark({
138
+ strategy,
139
+ browserlessFactory,
100
140
  concurrency,
101
- createBrowserless: createBrowserless({ puppeteer, ...opts }),
141
+ getStats,
102
142
  iterations,
103
143
  method,
104
- url,
105
- opts
144
+ opts,
145
+ url
106
146
  })
107
147
 
108
- const stats = reduce(
109
- histogram,
110
- (acc, value, key) => {
111
- const newValue = !includes(['count'], key) ? prettyMs(value) : value
112
- return { ...acc, [key]: newValue }
113
- },
114
- {}
115
- )
148
+ const graph = asciichart.plot(times, {
149
+ offset: 6,
150
+ height: 10,
151
+ format: time => prettyMs(time, { keepDecimalsOnWholeSeconds: true })
152
+ })
116
153
 
117
- const graph = asciichart.plot(times, { height: 6 })
118
- const { memUsed } = processStats.process()
154
+ await strategy.onClose(browserlessFactory)
155
+ const { uptime, memUsed } = getStats()
156
+ getStats.destroy()
119
157
 
120
158
  console.log()
121
159
  console.log(graph)
122
- console.log(prettyObj({ memUsed: memUsed.pretty, ...stats }))
160
+ console.log(`
161
+ ${gray(' time:')} ${uptime.pretty}
162
+ ${gray(' count:')} ${histogram.count}
163
+ ${gray(' memUsed:')} ${memUsed.pretty}
164
+ ${gray(' min:')} ${prettyMs(histogram.min)}
165
+ ${gray(' max:')} ${prettyMs(histogram.max)}
166
+ ${gray(' median:')} ${prettyMs(histogram.median)}
167
+ ${gray(' p75:')} ${prettyMs(histogram.p75)}
168
+ ${gray(' p95:')} ${prettyMs(histogram.p95)}
169
+ ${gray(' p99:')} ${prettyMs(histogram.p99)}
170
+ ${gray(' p999:')} ${prettyMs(histogram.p999)}`)
123
171
  }
124
172
 
125
173
  main()