├── client
├── versions.js
├── benchmarks.js
├── main.js
├── utils
│ └── sequence.js
├── measurements.js
├── components
│ ├── Results.html
│ ├── BenchmarkResult.html
│ └── Main.html
└── run.js
├── .gitignore
├── scripts
├── build.js
├── install.js
└── build-tools.js
├── selenium
├── measurements.js
└── run.js
├── server
└── index.js
├── README.md
├── benchmarks
├── hello-world
│ └── Main.html
├── create-large-table
│ └── Main.html
└── dbmonster
│ ├── Main.html
│ └── ENV.js
├── public
└── index.html
├── rollup.config.js
├── versions.json
├── .eslintrc.json
├── package.json
└── yarn.lock
/client/versions.js:
--------------------------------------------------------------------------------
1 | export default __VERSIONS__;
--------------------------------------------------------------------------------
/client/benchmarks.js:
--------------------------------------------------------------------------------
1 | export default __BENCHMARKS__;
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | public/benchmarks
4 | public/bundle*
5 | versions/
--------------------------------------------------------------------------------
/client/main.js:
--------------------------------------------------------------------------------
1 | import Main from './components/Main.html';
2 |
3 | const app = new Main({
4 | target: document.querySelector( 'main' )
5 | });
--------------------------------------------------------------------------------
/client/utils/sequence.js:
--------------------------------------------------------------------------------
1 | export default function sequence ( array, fn ) {
2 | return array.reduce( ( promise, item ) => {
3 | return promise.then( () => Promise.resolve( fn( item ) ) );
4 | }, Promise.resolve() );
5 | }
--------------------------------------------------------------------------------
/scripts/build.js:
--------------------------------------------------------------------------------
1 | const { build } = require('./build-tools');
2 |
3 | const versions = require( '../versions.json' );
4 |
5 | versions.forEach( version => {
6 | const dir = `versions/${version}`;
7 | build( version, dir );
8 | });
--------------------------------------------------------------------------------
/client/measurements.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | id: 'create:cold'
4 | },
5 | {
6 | id: 'create:warm'
7 | },
8 | {
9 | id: 'run:cold'
10 | },
11 | {
12 | id: 'run:warm'
13 | },
14 | {
15 | id: 'destroy:cold'
16 | },
17 | {
18 | id: 'destroy:warm'
19 | }
20 | ];
--------------------------------------------------------------------------------
/selenium/measurements.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | {
3 | id: 'create:cold'
4 | },
5 | {
6 | id: 'create:warm'
7 | },
8 | {
9 | id: 'run:cold'
10 | },
11 | {
12 | id: 'run:warm'
13 | },
14 | {
15 | id: 'destroy:cold'
16 | },
17 | {
18 | id: 'destroy:warm'
19 | }
20 | ];
--------------------------------------------------------------------------------
/server/index.js:
--------------------------------------------------------------------------------
1 | const fs = require( 'fs' );
2 | const path = require( 'path' );
3 | const relative = require( 'require-relative' );
4 | const express = require( 'express' );
5 | const { rollup } = require( 'rollup' );
6 |
7 | const app = express();
8 |
9 | app.use( express.static( `public` ) );
10 |
11 | app.listen( 3000, () => {
12 | console.log( `Listening on localhost:3000` );
13 | });
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # svelte-bench
2 |
3 | Benchmarks for [Svelte](https://svelte.technology). Work-in-progress.
4 |
5 | ## Running the benchmarks
6 |
7 | You must have [Yarn](https://yarnpkg.com) installed.
8 |
9 | ```bash
10 | git clone https://github.com/sveltejs/svelte-bench
11 | cd svelte-bench
12 | yarn
13 | yarn start
14 | ```
15 |
16 | Navigate to [localhost:3000](http://localhost:3000).
17 |
--------------------------------------------------------------------------------
/benchmarks/hello-world/Main.html:
--------------------------------------------------------------------------------
1 |
hello {{name}}!
2 |
3 |
--------------------------------------------------------------------------------
/scripts/install.js:
--------------------------------------------------------------------------------
1 | const { execSync } = require( 'child_process' );
2 | const sander = require( 'sander' );
3 |
4 | const versions = require( '../versions.json' );
5 |
6 | versions.forEach( version => {
7 | sander.writeFileSync( `versions/${version}/package.json`, JSON.stringify({
8 | dependencies: {
9 | svelte: version
10 | }
11 | }));
12 |
13 | execSync( `yarn`, {
14 | cwd: `versions/${version}`,
15 | stdio: 'inherit'
16 | });
17 | });
--------------------------------------------------------------------------------
/client/components/Results.html:
--------------------------------------------------------------------------------
1 |
2 | {{#each benchmarks as benchmark}}
3 |
4 | {{/each}}
5 |
6 |
7 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | svelte-bench
8 |
9 |
14 |
15 |
16 |
17 | svelte-bench
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/benchmarks/create-large-table/Main.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | | a |
5 | b |
6 | c |
7 | d |
8 |
9 |
10 |
11 |
12 | {{#each rows as row}}
13 |
14 | | {{row[0]}} |
15 | {{row[1]}} |
16 | {{row[2]}} |
17 | {{row[3]}} |
18 |
19 | {{/each}}
20 |
21 |
22 |
23 |
39 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import replace from 'rollup-plugin-replace';
3 | import svelte from 'rollup-plugin-svelte';
4 | import commonjs from 'rollup-plugin-commonjs';
5 | import resolve from 'rollup-plugin-node-resolve';
6 |
7 | // TODO should this list be automatically generated somehow?
8 | const versions = require( './versions.json' );
9 |
10 | const benchmarks = fs.readdirSync( 'benchmarks' ).filter( d => d[0] !== '.' );
11 |
12 | export default {
13 | entry: 'client/main.js',
14 | dest: 'public/bundle.js',
15 | format: 'iife',
16 | sourceMap: true,
17 | plugins: [
18 | resolve(),
19 | commonjs(),
20 | replace({
21 | __BENCHMARKS__: JSON.stringify( benchmarks ),
22 | __VERSIONS__: JSON.stringify( versions )
23 | }),
24 | svelte()
25 | ]
26 | };
--------------------------------------------------------------------------------
/versions.json:
--------------------------------------------------------------------------------
1 | [
2 | "1.22.0",
3 | "1.21.0",
4 | "1.20.2",
5 | "1.20.1",
6 | "1.20.0",
7 | "1.19.1",
8 | "1.19.0",
9 | "1.18.2",
10 | "1.18.1",
11 | "1.18.0",
12 | "1.17.2",
13 | "1.17.1",
14 | "1.17.0",
15 | "1.16.0",
16 | "1.15.1",
17 | "1.15.0",
18 | "1.14.1",
19 | "1.14.0",
20 | "1.13.7",
21 | "1.13.6",
22 | "1.13.5",
23 | "1.13.4",
24 | "1.13.3",
25 | "1.13.2",
26 | "1.13.1",
27 | "1.13.0",
28 | "1.12.1",
29 | "1.12.0",
30 | "1.11.4",
31 | "1.11.3",
32 | "1.11.2",
33 | "1.11.1",
34 | "1.11.0",
35 | "1.10.3",
36 | "1.10.2",
37 | "1.10.1",
38 | "1.10.0",
39 | "1.9.1",
40 | "1.9.0",
41 | "1.8.1",
42 | "1.8.0",
43 | "1.6.11",
44 | "1.6.10",
45 | "1.6.9",
46 | "1.6.8",
47 | "1.6.7",
48 | "1.6.6",
49 | "1.6.5",
50 | "1.6.4",
51 | "1.6.3",
52 | "1.6.2",
53 | "1.6.1",
54 | "1.6.0",
55 | "1.5.0",
56 | "1.4.0",
57 | "1.3.1",
58 | "1.3.0",
59 | "1.2.5",
60 | "1.2.4",
61 | "1.2.3",
62 | "1.2.2",
63 | "1.2.1",
64 | "1.2.0",
65 | "1.1.3",
66 | "1.1.2",
67 | "1.1.1",
68 | "1.1.0",
69 | "1.0.7",
70 | "1.0.6"
71 | ]
72 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "rules": {
4 | "indent": [ 2, "tab", { "SwitchCase": 1 } ],
5 | "semi": [ 2, "always" ],
6 | "keyword-spacing": [ 2, { "before": true, "after": true } ],
7 | "space-before-blocks": [ 2, "always" ],
8 | "space-before-function-paren": [ 2, "always" ],
9 | "no-mixed-spaces-and-tabs": [ 2, "smart-tabs" ],
10 | "no-cond-assign": 0,
11 | "no-unused-vars": 2,
12 | "object-shorthand": [ 2, "always" ],
13 | "no-const-assign": 2,
14 | "no-class-assign": 2,
15 | "no-this-before-super": 2,
16 | "no-var": 2,
17 | "no-unreachable": 2,
18 | "valid-typeof": 2,
19 | "quote-props": [ 2, "as-needed" ],
20 | "one-var": [ 2, "never" ],
21 | "prefer-arrow-callback": 2,
22 | "prefer-const": [ 2, { "destructuring": "all" } ],
23 | "arrow-spacing": 2,
24 | "no-inner-declarations": 0
25 | },
26 | "env": {
27 | "es6": true,
28 | "browser": true,
29 | "node": true,
30 | "mocha": true
31 | },
32 | "extends": [
33 | "eslint:recommended",
34 | "plugin:import/errors",
35 | "plugin:import/warnings"
36 | ],
37 | "parserOptions": {
38 | "ecmaVersion": 6,
39 | "sourceType": "module"
40 | },
41 | "settings": {
42 | "import/core-modules": [ "svelte" ]
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "svelte-bench",
3 | "version": "1.0.0",
4 | "description": "Svelte benchmarks",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "npm run build:benchmarks && npm run build:client && node server",
8 | "build:client": "rollup -c",
9 | "build:benchmarks": "node scripts/build",
10 | "postinstall": "node scripts/install",
11 | "dev": "rollup -c -w",
12 | "test": "echo \"Error: no test specified\" && exit 1"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "git+https://github.com/sveltejs/svelte-bench.git"
17 | },
18 | "keywords": [
19 | "svelte",
20 | "benchmark",
21 | "perf"
22 | ],
23 | "author": "Rich Harris",
24 | "license": "MIT",
25 | "bugs": {
26 | "url": "https://github.com/sveltejs/svelte-bench/issues"
27 | },
28 | "homepage": "https://github.com/sveltejs/svelte-bench#readme",
29 | "devDependencies": {
30 | "eslint": "^3.17.1",
31 | "eslint-plugin-import": "^2.2.0",
32 | "require-relative": "^0.8.7",
33 | "rollup": "^0.41.5",
34 | "rollup-plugin-buble": "^0.15.0",
35 | "rollup-plugin-commonjs": "^8.0.2",
36 | "rollup-plugin-node-resolve": "^2.0.0",
37 | "rollup-plugin-replace": "^1.1.1",
38 | "rollup-plugin-svelte": "^1.6.0",
39 | "rollup-watch": "^3.2.2",
40 | "sander": "^0.6.0",
41 | "uglify-js": "^2.8.12"
42 | },
43 | "dependencies": {
44 | "chalk": "^1.1.3",
45 | "chroma-js": "^1.2.2",
46 | "express": "^4.15.2",
47 | "minimist": "^1.2.0",
48 | "selenium-webdriver": "^3.3.0"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/benchmarks/dbmonster/Main.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{#each dbs as db}}
4 |
5 | |
6 | {{ db.dbname }}
7 | |
8 |
9 |
10 |
11 | {{ db.lastSample.nbQueries }}
12 |
13 | |
14 |
15 | {{#each db.lastSample.topFiveQueries as query}}
16 |
17 | {{ query.formatElapsed }}
18 |
19 | {{ query.query }}
20 |
21 |
22 | |
23 | {{/each}}
24 |
25 | {{/each}}
26 |
27 |
28 |
29 |
63 |
64 |
--------------------------------------------------------------------------------
/client/components/BenchmarkResult.html:
--------------------------------------------------------------------------------
1 |
2 |
{{benchmark}}
3 |
4 |
5 |
6 |
7 | | version |
8 | size |
9 | {{#each measurements as measurement}}
10 | {{measurement.id}} |
11 | {{/each}}
12 |
13 |
14 |
15 |
16 | {{#each rows as row}}
17 |
18 | | {{row.version}} |
19 | {{row.size}} |
20 | {{#each row.measurements as cell}}
21 |
22 |
23 | {{cell.label}}
24 | |
25 | {{/each}}
26 |
27 | {{/each}}
28 |
29 |
30 |
31 |
32 |
63 |
64 |
--------------------------------------------------------------------------------
/client/run.js:
--------------------------------------------------------------------------------
1 | /*global Component */
2 | export function createAndDestroy () {
3 | if ( window.error ) {
4 | window.opener.postMessage({
5 | type: 'error',
6 | message: window.error
7 | }, '*' );
8 |
9 | window.opener.postMessage({
10 | type: 'done'
11 | }, '*' );
12 |
13 | return;
14 | }
15 |
16 | const now = () => window.performance.now();
17 | const wait = window.setImmediate ?
18 | () => new Promise( fulfil => setImmediate( fulfil ) ) :
19 | () => new Promise( fulfil => setTimeout( fulfil, 0 ) );
20 |
21 | function runCold () {
22 | let component;
23 |
24 | return Promise.resolve()
25 | .then( () => {
26 | // component create
27 | const t = now();
28 | component = new Component({
29 | target: document.body
30 | });
31 | const duration = now() - t;
32 |
33 | window.opener.postMessage({
34 | type: 'create:cold',
35 | value: duration
36 | }, '*' );
37 | })
38 | .then( wait )
39 | .then( () => {
40 | // component run
41 | let duration = 0;
42 |
43 | if ( component.run ) {
44 | const t = now();
45 | component.run();
46 | duration = now() - t;
47 | }
48 |
49 | window.opener.postMessage({
50 | type: 'run:cold',
51 | value: duration
52 | }, '*' );
53 | })
54 | .then( wait )
55 | .then( () => {
56 | // component destroy
57 | const t = now();
58 | if ( component.destroy ) {
59 | component.destroy();
60 | } else {
61 | component.teardown();
62 | }
63 | const duration = now() - t;
64 |
65 | window.opener.postMessage({
66 | type: 'destroy:cold',
67 | value: duration
68 | }, '*' );
69 | });
70 | }
71 |
72 | function runWarm () {
73 | const iterations = 5;
74 |
75 | // warm up
76 | let i = 50;
77 | while ( i-- ) {
78 | const component = new Component({
79 | target: document.body
80 | });
81 |
82 | if ( component.run ) {
83 | component.run();
84 | }
85 |
86 | if ( component.destroy ) {
87 | component.destroy();
88 | } else {
89 | component.teardown();
90 | }
91 | }
92 |
93 | // time warm runs
94 | i = iterations;
95 |
96 | let createTotal = 0;
97 | let runTotal = 0;
98 | let destroyTotal = 0;
99 |
100 | function go () {
101 | let component;
102 |
103 | return Promise.resolve()
104 | .then( () => {
105 | const t = now();
106 | component = new Component({
107 | target: document.body
108 | });
109 | createTotal += now() - t;
110 | })
111 | .then( wait )
112 | .then( () => {
113 | if ( component.run ) {
114 | const t = now();
115 | component.run();
116 | runTotal += now() - t;
117 | }
118 | })
119 | .then( wait )
120 | .then( () => {
121 | const t = now();
122 | if ( component.destroy ) {
123 | component.destroy();
124 | } else {
125 | component.teardown();
126 | }
127 | destroyTotal += now() - t;
128 | })
129 | .then( () => {
130 | if ( --i > 0 ) return go();
131 | });
132 | }
133 |
134 | return go().then( () => {
135 | window.opener.postMessage({
136 | type: 'create:warm',
137 | value: createTotal / iterations
138 | }, '*' );
139 |
140 | window.opener.postMessage({
141 | type: 'run:warm',
142 | value: runTotal / iterations
143 | }, '*' );
144 |
145 | window.opener.postMessage({
146 | type: 'destroy:warm',
147 | value: destroyTotal / iterations
148 | }, '*' );
149 | });
150 | }
151 |
152 | runCold()
153 | .then( runWarm )
154 | .then( () => {
155 | window.opener.postMessage({
156 | type: 'done'
157 | }, '*' );
158 | });
159 | }
--------------------------------------------------------------------------------
/scripts/build-tools.js:
--------------------------------------------------------------------------------
1 | const path = require( 'path' );
2 | const sander = require( 'sander' );
3 | const { rollup } = require( 'rollup' );
4 | const buble = require( 'rollup-plugin-buble' );
5 | const UglifyJS = require( 'uglify-js' );
6 | const zlib = require( 'zlib' );
7 | const relative = require( 'require-relative' );
8 |
9 | const benchmarks = sander.readdirSync( 'benchmarks' ).filter( d => d[0] !== '.' );
10 |
11 | module.exports.build = function ( version, dir, custom ) {
12 | const svelte = path.basename( dir ) === 'svelte' ? require(dir) : relative( 'svelte', dir );
13 |
14 | let promise = Promise.resolve();
15 | benchmarks.forEach( benchmark => {
16 | promise = promise.then(() => {
17 | const dest = `public/benchmarks/${benchmark}/${version}`;
18 |
19 | return ( custom ? Promise.resolve( false ) : sander.exists( dest ) ).then( exists => {
20 | if ( exists ) return;
21 |
22 | return rollup({
23 | entry: `benchmarks/${benchmark}/Main.html`,
24 | plugins: [
25 | {
26 | name: 'svelte',
27 |
28 | transform ( code, id ) {
29 | if ( !/\.html$/.test( id ) ) { return null; }
30 |
31 | const name = path.basename( id ).replace( /\.html$/, '' );
32 |
33 | return svelte.compile( code, {
34 | name,
35 | filename: id,
36 | format: 'es',
37 | shared: custom ? path.join( dir, 'shared.js' ) : relative.resolve( 'svelte/shared.js', dir ),
38 |
39 | onerror ( err ) {
40 | let message = ( err.loc ? `(${err.loc.line}:${err.loc.column}) ` : '' ) + err.message;
41 | if ( err.frame ) message += `\n${err.frame}`;
42 |
43 | const err2 = new Error( message );
44 | err2.stack = err.stack;
45 |
46 | throw err2;
47 | }
48 | });
49 | }
50 | },
51 | buble()
52 | ]
53 | }).then( bundle => {
54 | return bundle.generate({
55 | format: 'iife',
56 | moduleName: 'Component'
57 | }).code;
58 | }, err => {
59 | console.error( err.message );
60 | return `window.error = ${JSON.stringify( err.message )};`;
61 | })
62 | .then( code => {
63 | const minified = UglifyJS.minify( code, { fromString: true });
64 | const zipped = zlib.gzipSync( minified.code );
65 |
66 | return Promise.all([
67 | sander.writeFile( `${dest}/component.js`, code ),
68 | sander.writeFile( `${dest}/index.html`, `
69 |
70 |
71 |
72 |
73 |
74 |
75 | ${benchmark}/${version}
76 |
77 |
82 |
83 |
84 | ${benchmark}/${version}
85 |
86 |
87 |
88 |
103 |
104 | ` ),
105 | sander.writeFile( `${dest}/component.json`, JSON.stringify({
106 | code,
107 | size: zipped.length
108 | }))
109 | ]);
110 | });
111 | });
112 | });
113 | });
114 |
115 | return promise;
116 | };
117 |
--------------------------------------------------------------------------------
/client/components/Main.html:
--------------------------------------------------------------------------------
1 |
8 |
9 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
--------------------------------------------------------------------------------
/benchmarks/dbmonster/ENV.js:
--------------------------------------------------------------------------------
1 | var first = true;
2 | var counter = 0;
3 | var data;
4 | var _base;
5 | (_base = String.prototype).lpad || (_base.lpad = function(padding, toLength) {
6 | return padding.repeat((toLength - this.length) / padding.length).concat(this);
7 | });
8 |
9 | function formatElapsed(value) {
10 | var str = parseFloat(value).toFixed(2);
11 | if (value > 60) {
12 | minutes = Math.floor(value / 60);
13 | comps = (value % 60).toFixed(2).split('.');
14 | seconds = comps[0].lpad('0', 2);
15 | ms = comps[1];
16 | str = minutes + ":" + seconds + "." + ms;
17 | }
18 | return str;
19 | }
20 |
21 | function getElapsedClassName(elapsed) {
22 | var className = 'Query elapsed';
23 | if (elapsed >= 10.0) {
24 | className += ' warn_long';
25 | }
26 | else if (elapsed >= 1.0) {
27 | className += ' warn';
28 | }
29 | else {
30 | className += ' short';
31 | }
32 | return className;
33 | }
34 |
35 | function countClassName(queries) {
36 | var countClassName = "label";
37 | if (queries >= 20) {
38 | countClassName += " label-important";
39 | }
40 | else if (queries >= 10) {
41 | countClassName += " label-warning";
42 | }
43 | else {
44 | countClassName += " label-success";
45 | }
46 | return countClassName;
47 | }
48 |
49 | function updateQuery(object) {
50 | if (!object) {
51 | object = {};
52 | }
53 | var elapsed = Math.random() * 15;
54 | object.elapsed = elapsed;
55 | object.formatElapsed = formatElapsed(elapsed);
56 | object.elapsedClassName = getElapsedClassName(elapsed);
57 | object.query = "SELECT blah FROM something";
58 | object.waiting = Math.random() < 0.5;
59 | if (Math.random() < 0.2) {
60 | object.query = " in transaction";
61 | }
62 | if (Math.random() < 0.1) {
63 | object.query = "vacuum";
64 | }
65 | return object;
66 | }
67 |
68 | function cleanQuery(value) {
69 | if (value) {
70 | value.formatElapsed = "";
71 | value.elapsedClassName = "";
72 | value.query = "";
73 | delete value.elapsed;
74 | delete value.waiting;
75 | } else {
76 | return {
77 | query: "***",
78 | formatElapsed: "",
79 | elapsedClassName: ""
80 | };
81 | }
82 | }
83 |
84 | function generateRow(object, keepIdentity, counter) {
85 | var nbQueries = Math.floor((Math.random() * 10) + 1);
86 | if (!object) {
87 | object = {};
88 | }
89 | object.lastMutationId = counter;
90 | object.nbQueries = nbQueries;
91 | if (!object.lastSample) {
92 | object.lastSample = {};
93 | }
94 | if (!object.lastSample.topFiveQueries) {
95 | object.lastSample.topFiveQueries = [];
96 | }
97 | if (keepIdentity) {
98 | // for Angular optimization
99 | if (!object.lastSample.queries) {
100 | object.lastSample.queries = [];
101 | for (var l = 0; l < 12; l++) {
102 | object.lastSample.queries[l] = cleanQuery();
103 | }
104 | }
105 | for (var j in object.lastSample.queries) {
106 | var value = object.lastSample.queries[j];
107 | if (j <= nbQueries) {
108 | updateQuery(value);
109 | } else {
110 | cleanQuery(value);
111 | }
112 | }
113 | } else {
114 | object.lastSample.queries = [];
115 | for (var j = 0; j < 12; j++) {
116 | if (j < nbQueries) {
117 | var value = updateQuery(cleanQuery());
118 | object.lastSample.queries.push(value);
119 | } else {
120 | object.lastSample.queries.push(cleanQuery());
121 | }
122 | }
123 | }
124 | for (var i = 0; i < 5; i++) {
125 | var source = object.lastSample.queries[i];
126 | object.lastSample.topFiveQueries[i] = source;
127 | }
128 | object.lastSample.nbQueries = nbQueries;
129 | object.lastSample.countClassName = countClassName(nbQueries);
130 | return object;
131 | }
132 |
133 | function getData(keepIdentity) {
134 | var oldData = data;
135 | if (!keepIdentity) { // reset for each tick when !keepIdentity
136 | data = [];
137 | for (var i = 1; i <= ENV.rows; i++) {
138 | data.push({ dbname: 'cluster' + i, query: "", formatElapsed: "", elapsedClassName: "" });
139 | data.push({ dbname: 'cluster' + i + ' slave', query: "", formatElapsed: "", elapsedClassName: "" });
140 | }
141 | }
142 | if (!data) { // first init when keepIdentity
143 | data = [];
144 | for (var i = 1; i <= ENV.rows; i++) {
145 | data.push({ dbname: 'cluster' + i });
146 | data.push({ dbname: 'cluster' + i + ' slave' });
147 | }
148 | oldData = data;
149 | }
150 | for (var i in data) {
151 | var row = data[i];
152 | if (!keepIdentity && oldData && oldData[i]) {
153 | row.lastSample = oldData[i].lastSample;
154 | }
155 | if (!row.lastSample || Math.random() < ENV.mutations()) {
156 | counter = counter + 1;
157 | if (!keepIdentity) {
158 | delete row.lastSample;
159 | }
160 | generateRow(row, keepIdentity, counter);
161 | } else {
162 | data[i] = oldData[i];
163 | }
164 | }
165 | first = false;
166 | return {
167 | toArray: function() {
168 | return data;
169 | }
170 | };
171 | }
172 |
173 | var mutationsValue = 0.5;
174 |
175 | function mutations(value) {
176 | if (value) {
177 | mutationsValue = value;
178 | return mutationsValue;
179 | } else {
180 | return mutationsValue;
181 | }
182 | }
183 |
184 | var body = document.querySelector('body');
185 | var theFirstChild = body.firstChild;
186 |
187 | var sliderContainer = document.createElement( 'div' );
188 | sliderContainer.style.cssText = "display: flex";
189 | var slider = document.createElement('input');
190 | var text = document.createElement('label');
191 | text.innerHTML = 'mutations : ' + (mutationsValue * 100).toFixed(0) + '%';
192 | text.id = "ratioval";
193 | slider.setAttribute("type", "range");
194 | slider.style.cssText = 'margin-bottom: 10px; margin-top: 5px';
195 | slider.addEventListener('change', function(e) {
196 | ENV.mutations(e.target.value / 100);
197 | document.querySelector('#ratioval').innerHTML = 'mutations : ' + (ENV.mutations() * 100).toFixed(0) + '%';
198 | });
199 | sliderContainer.appendChild( text );
200 | sliderContainer.appendChild( slider );
201 | body.insertBefore( sliderContainer, theFirstChild );
202 |
203 | const ENV = {
204 | generateData: getData,
205 | rows: 50,
206 | timeout: 0,
207 | mutations: mutations
208 | };
209 |
210 | export default ENV;
--------------------------------------------------------------------------------
/selenium/run.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const {Builder, By, until} = require('selenium-webdriver');
3 | const chalk = require('chalk');
4 | const minimist = require('minimist');
5 | const {build} = require('../scripts/build-tools');
6 |
7 | const command = minimist(process.argv.slice(2));
8 |
9 | const capabilities = command.capabilities ? JSON.parse(command.capabilities) : [];
10 | const server = command.server || null;
11 | const browsers = command.browsers ? command.browsers.split(',') : [];
12 | const iterations = command.iterations ? +command.iterations : 5;
13 | const output = command.output || null;
14 |
15 | const allVersions = require('../versions.json').map(version => {
16 | const split = version.split('.');
17 | return {
18 | major: +split[0],
19 | minor: +split[1],
20 | patch: +split[2]
21 | };
22 | });
23 | const benchmarks = fs.readdirSync('benchmarks').filter(d => d[0] !== '.');
24 | const measurements = require('./measurements');
25 |
26 | const versions = [];
27 | allVersions.forEach(version => {
28 | if (versions.length < 5) {
29 | versions.push(`${version.major}.${version.minor}.${version.patch}`);
30 | } else if (versions.length < 10 && allVersions.filter(other => other.major === version.major && other.minor === version.minor && other.patch > version.patch).length === 0) {
31 | versions.push(`${version.major}.${version.minor}.${version.patch}`);
32 | }
33 | });
34 | console.log('Running versions', versions.join(', '));
35 |
36 | const combinations = [];
37 |
38 | if (command.custom) {
39 | build('custom', command.custom, true).then(run);
40 | versions.unshift('custom');
41 | } else {
42 | run();
43 | }
44 |
45 | if (output && fs.existsSync(output)) {
46 | fs.unlinkSync(output);
47 | }
48 |
49 | function createDriver(results, browser, cap) {
50 | let driverInstance;
51 |
52 | let builder = new Builder();
53 | if (server) {
54 | builder = builder.usingServer(server);
55 | }
56 | if (browser) {
57 | builder = builder.forBrowser(browser);
58 | }
59 | if (cap) {
60 | builder = builder.withCapabilities(cap);
61 | }
62 |
63 | const capString = browser || `${cap.browserName} ${cap.version} (${cap.platform})`;
64 |
65 | driverInstance = builder.build();
66 | driverInstance.manage().timeouts().setScriptTimeout(5 * 1000);
67 | return sequence(combinations, ({version, benchmark, code, size}) => {
68 | console.log('Testing', version, benchmark, 'in', capString);
69 |
70 | results[benchmark][version] = {};
71 |
72 | results[benchmark][version].size = size;
73 |
74 | const base64 = Buffer.from(`
75 |