Skip to content

Commit

Permalink
feat(best-compare): Fix comparer recursivity (#65)
Browse files Browse the repository at this point in the history
* Fix comparison recursivity
* Prettify
  • Loading branch information
diervo committed Feb 4, 2018
1 parent 04e946c commit bf6efec
Show file tree
Hide file tree
Showing 17 changed files with 113 additions and 114 deletions.
7 changes: 2 additions & 5 deletions best.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
module.exports = {
"projectName": "perf-best-examples",
projects: [
'<rootDir>/examples/simple_benchmark',
'<rootDir>/examples/simple_lwc_benchmark',
]
projectName: 'perf-best-examples',
projects: ['<rootDir>/examples/simple_benchmark', '<rootDir>/examples/simple_lwc_benchmark'],
};
93 changes: 44 additions & 49 deletions examples/simple_benchmark/src/__benchmarks__/deep_merge.js
Original file line number Diff line number Diff line change
@@ -1,89 +1,84 @@
// https://unpkg.com/deepmerge@2.0.1/dist/es.js

var isMergeableObject = function isMergeableObject(value) {
return isNonNullObject(value)
&& !isSpecial(value)
return isNonNullObject(value) && !isSpecial(value);
};

function isNonNullObject(value) {
return !!value && typeof value === 'object'
return !!value && typeof value === 'object';
}

function isSpecial(value) {
var stringValue = Object.prototype.toString.call(value);
var stringValue = Object.prototype.toString.call(value);

return stringValue === '[object RegExp]'
|| stringValue === '[object Date]'
|| isReactElement(value)
return stringValue === '[object RegExp]' || stringValue === '[object Date]' || isReactElement(value);
}

// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25
var canUseSymbol = typeof Symbol === 'function' && Symbol.for;
var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;

function isReactElement(value) {
return value.$$typeof === REACT_ELEMENT_TYPE
return value.$$typeof === REACT_ELEMENT_TYPE;
}

function emptyTarget(val) {
return Array.isArray(val) ? [] : {}
return Array.isArray(val) ? [] : {};
}

function cloneUnlessOtherwiseSpecified(value, optionsArgument) {
var clone = !optionsArgument || optionsArgument.clone !== false;
var clone = !optionsArgument || optionsArgument.clone !== false;

return (clone && isMergeableObject(value))
? deepmerge(emptyTarget(value), value, optionsArgument)
: value
return clone && isMergeableObject(value) ? deepmerge(emptyTarget(value), value, optionsArgument) : value;
}

function defaultArrayMerge(target, source, optionsArgument) {
return target.concat(source).map(function(element) {
return cloneUnlessOtherwiseSpecified(element, optionsArgument)
})
return target.concat(source).map(function(element) {
return cloneUnlessOtherwiseSpecified(element, optionsArgument);
});
}

function mergeObject(target, source, optionsArgument) {
var destination = {};
if (isMergeableObject(target)) {
Object.keys(target).forEach(function(key) {
destination[key] = cloneUnlessOtherwiseSpecified(target[key], optionsArgument);
});
}
Object.keys(source).forEach(function(key) {
if (!isMergeableObject(source[key]) || !target[key]) {
destination[key] = cloneUnlessOtherwiseSpecified(source[key], optionsArgument);
} else {
destination[key] = deepmerge(target[key], source[key], optionsArgument);
}
});
return destination
var destination = {};
if (isMergeableObject(target)) {
Object.keys(target).forEach(function(key) {
destination[key] = cloneUnlessOtherwiseSpecified(target[key], optionsArgument);
});
}
Object.keys(source).forEach(function(key) {
if (!isMergeableObject(source[key]) || !target[key]) {
destination[key] = cloneUnlessOtherwiseSpecified(source[key], optionsArgument);
} else {
destination[key] = deepmerge(target[key], source[key], optionsArgument);
}
});
return destination;
}

function deepmerge(target, source, optionsArgument) {
var sourceIsArray = Array.isArray(source);
var targetIsArray = Array.isArray(target);
var options = optionsArgument || { arrayMerge: defaultArrayMerge };
var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;

if (!sourceAndTargetTypesMatch) {
return cloneUnlessOtherwiseSpecified(source, optionsArgument)
} else if (sourceIsArray) {
var arrayMerge = options.arrayMerge || defaultArrayMerge;
return arrayMerge(target, source, optionsArgument)
} else {
return mergeObject(target, source, optionsArgument)
}
var sourceIsArray = Array.isArray(source);
var targetIsArray = Array.isArray(target);
var options = optionsArgument || { arrayMerge: defaultArrayMerge };
var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;

if (!sourceAndTargetTypesMatch) {
return cloneUnlessOtherwiseSpecified(source, optionsArgument);
} else if (sourceIsArray) {
var arrayMerge = options.arrayMerge || defaultArrayMerge;
return arrayMerge(target, source, optionsArgument);
} else {
return mergeObject(target, source, optionsArgument);
}
}

deepmerge.all = function deepmergeAll(array, optionsArgument) {
if (!Array.isArray(array)) {
throw new Error('first argument should be an array')
}
if (!Array.isArray(array)) {
throw new Error('first argument should be an array');
}

return array.reduce(function(prev, next) {
return deepmerge(prev, next, optionsArgument)
}, {})
return array.reduce(function(prev, next) {
return deepmerge(prev, next, optionsArgument);
}, {});
};

var deepmerge_1 = deepmerge;
Expand Down
40 changes: 20 additions & 20 deletions examples/simple_benchmark/src/__benchmarks__/mock_data.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
export const MOCK_DATA_SMALL = {
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters": {
"batter":[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
id: '0001',
type: 'donut',
name: 'Cake',
ppu: 0.55,
batters: {
batter: [
{ id: '1001', type: 'Regular' },
{ id: '1002', type: 'Chocolate' },
{ id: '1003', type: 'Blueberry' },
{ id: '1004', type: "Devil's Food" },
],
},
"topping": [
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
topping: [
{ id: '5001', type: 'None' },
{ id: '5002', type: 'Glazed' },
{ id: '5005', type: 'Sugar' },
{ id: '5007', type: 'Powdered Sugar' },
{ id: '5006', type: 'Chocolate with Sprinkles' },
{ id: '5003', type: 'Chocolate' },
{ id: '5004', type: 'Maple' },
],
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MOCK_DATA_SMALL } from "./mock_data";
import merge from "./deep_merge";
import { MOCK_DATA_SMALL } from './mock_data';
import merge from './deep_merge';

describe('deep_clone', () => {
benchmark('stringify_parse', () => {
Expand Down
2 changes: 1 addition & 1 deletion examples/simple_lwc_benchmark/best.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module.exports = {
plugins: {
'rollup-plugin-lwc-compiler': {
rootDir: '<rootDir>/src/',
mode: 'dev' // We don't really need prod here since this is for test best itself
mode: 'dev', // We don't really need prod here since this is for test best itself
},
},
benchmarkOnClient: false,
Expand Down
2 changes: 1 addition & 1 deletion packages/best-analyzer/src/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export function compare(sample1, sample2) {
}

function getZ(n) {
return (n - (size1 * size2 / 2)) / Math.sqrt(size1 * size2 * (size1 + size2 + 1) / 12);
return (n - size1 * size2 / 2) / Math.sqrt(size1 * size2 * (size1 + size2 + 1) / 12);
}

if (size1 + size2 < 30) {
Expand Down
2 changes: 1 addition & 1 deletion packages/best-build/src/rollup-plugin-benchmark-import.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function resolveModuleEntryFromPackage(module) {
const BENCHMARK_RUNTIME_MODULE = '@best/runtime';
const BENCHMARK_IMPORT = `import { ${PRIMITIVES.join(',')} } from "${BENCHMARK_RUNTIME_MODULE}" \n`;

export default function () {
export default function() {
let input;
return {
name: 'benchmark-import',
Expand Down
3 changes: 1 addition & 2 deletions packages/best-cli/src/cli/args.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ export const options = {
},
projects: {
description:
'A list of projects that use Best to run all tests of all ' +
'projects in a single instance of Best.',
'A list of projects that use Best to run all tests of all ' + 'projects in a single instance of Best.',
type: 'array',
},
iterations: {
Expand Down
4 changes: 2 additions & 2 deletions packages/best-cli/src/cli/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import chalk from 'chalk';
function padding(n) {
return n > 0
? Array.apply(null, Array((n - 1) * 3))
.map(() => ' ')
.join('') + '└─ '
.map(() => ' ')
.join('') + '└─ '
: '';
}

Expand Down
4 changes: 1 addition & 3 deletions packages/best-compare/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function compareBenchmarks(baseBenchs, targetBenchs, comparison = []) {
}

if (baseBenchmark.benchmarks) {
compareBenchmarks(baseBenchmark.benchmarks, targetBenchmark.benchmarks);
comparison.push(...compareBenchmarks(baseBenchmark.benchmarks, targetBenchmark.benchmarks));
} else {
// For now compare only duration metrics, we should compare more things
const baseDurationMetrics = baseBenchmark.duration;
Expand Down Expand Up @@ -60,8 +60,6 @@ export async function compareBenchmarkStats(baseCommit, targetCommit, projectNam
comparison: [],
};

// console.log('>> ', baseBenchmarks, targetBenchmarks);

baseBenchmarks.forEach(baseBenchmarkBundle => {
const { benchmarkName } = baseBenchmarkBundle;
const targetBenchmarkBundle = targetBenchmarks.find(b => b.benchmarkName === benchmarkName);
Expand Down
8 changes: 5 additions & 3 deletions packages/best-config/src/git.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ function getRepository(cwd) {
child.on('close', code => {
if (code === 0) {
const rawValue = stdout.trim();
const [owner, repo] = rawValue.split(':')
const [owner, repo] = rawValue
.split(':')
.pop()
.split('.git')[0].split('/');
.split('.git')[0]
.split('/');
resolve({ owner, repo });
} else {
reject(code + ': ' + stderr);
Expand All @@ -68,7 +70,7 @@ export async function addGitInformation(options) {
getCurrentHash(cwd),
hasLocalChanges(cwd),
getBranch(cwd),
getRepository(cwd)
getRepository(cwd),
]);

return Object.assign(options, { gitCommit, gitLocalChanges, gitBranch, gitRepository });
Expand Down
16 changes: 10 additions & 6 deletions packages/best-config/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,7 @@ function normalizeRootDirPattern(str, rootDir) {
}

function normalizeUnmockedModulePathPatterns(options, key) {
return options[key].map(pattern =>
replacePathSepForRegex(normalizeRootDirPattern(pattern, options.rootDir))
);
return options[key].map(pattern => replacePathSepForRegex(normalizeRootDirPattern(pattern, options.rootDir)));
}

function normalizeObjectPathPatterns(options, { rootDir }) {
Expand Down Expand Up @@ -207,7 +205,7 @@ function _getConfigs(options) {
gitCommit: options.gitCommit,
gitLocalChanges: options.gitLocalChanges,
gitBranch: options.gitBranch,
gitRepository: options.gitRepository
gitRepository: options.gitRepository,
}),
projectConfig: Object.freeze({
cache: options.cache,
Expand Down Expand Up @@ -256,7 +254,13 @@ const ensureNoDuplicateConfigs = (parsedConfigs, projects) => {
let message = 'One or more specified projects share the same config file\n';

parsedConfigs.forEach((projectConfig, index) => {
message = message + '\nProject: "' + projects[index] + '"\nConfig: "' + String(projectConfig.configPath) + '"';
message =
message +
'\nProject: "' +
projects[index] +
'"\nConfig: "' +
String(projectConfig.configPath) +
'"';
});
throw new Error(message);
}
Expand Down Expand Up @@ -285,7 +289,7 @@ export async function readConfig(argsCLI, packageRoot, parentConfigPath) {
}

const { globalConfig, projectConfig } = _getConfigs(options);
return { configPath, globalConfig, projectConfig };
return { configPath, globalConfig, projectConfig };
}

export async function getConfigs(projectsFromCLIArgs, argv) {
Expand Down
30 changes: 16 additions & 14 deletions packages/best-github-integration/src/comment.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,23 @@ function template({ targetCommit, baseCommit, table }) {
]);
}

function generateRows(stats, name = '') {
return stats.comparison.map(node => {
function generateRows(stats, name = '', rows = []) {
return stats.comparison.reduce((allRows, node) => {
if (node.comparison) {
return generateRows(node, `${node.benchmarkName || node.name}:`).reduce((a, b) => a.concat(b));
}

const durationMetric = node.metrics.duration;
const { baseStats, targetStats, samplesComparison } = durationMetric;
generateRows(node, `${node.benchmarkName || node.name}:`, rows);
} else {
const durationMetric = node.metrics.duration;
const { baseStats, targetStats, samplesComparison } = durationMetric;

return [
name + node.name,
`${baseStats.median.toFixed(2)}${targetStats.medianAbsoluteDeviation.toFixed(2)} ms)`,
`${targetStats.median.toFixed(2)}${targetStats.medianAbsoluteDeviation.toFixed(2)} ms)`,
samplesComparison === 0 ? '👌' : samplesComparison === 1 ? '👎' : '👍',
];
});
allRows.push([
name + node.name,
`${baseStats.median.toFixed(2)}${targetStats.medianAbsoluteDeviation.toFixed(2)} ms)`,
`${targetStats.median.toFixed(2)}${targetStats.medianAbsoluteDeviation.toFixed(2)} ms)`,
samplesComparison === 0 ? '👌' : samplesComparison === 1 ? '👎' : '👍',
]);
}
return allRows;
}, rows);
}

function generateTable(baseCommit, targetCommit, stats) {
Expand All @@ -39,6 +40,7 @@ function generateTable(baseCommit, targetCommit, stats) {

export function generateComparisonComment(baseCommit, targetCommit, stats) {
const table = generateTable(baseCommit, targetCommit, stats);

return template({
baseCommit,
targetCommit,
Expand Down
2 changes: 1 addition & 1 deletion packages/best-runner-headless/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ async function normalizeEnvironment(browser, projectConfig, globalConfig) {
gitCommitHash: globalConfig.gitCommit,
gitHasLocalChanges: globalConfig.gitLocalChanges,
gitBranch: globalConfig.gitBranch,
gitRepository: globalConfig.gitRepository
gitRepository: globalConfig.gitRepository,
},
},
};
Expand Down
4 changes: 3 additions & 1 deletion packages/best-runtime/src/primitives-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ const handler = (event, state) => {

if (currentDescribeBlock.children.length === 0 && !currentDescribeBlock.run) {
throw new Error(
`Benchmark "${currentDescribeBlock.name}" must have a 'run()' function or contain benchmarks inside.`
`Benchmark "${
currentDescribeBlock.name
}" must have a 'run()' function or contain benchmarks inside.`,
);
}

Expand Down
Loading

0 comments on commit bf6efec

Please sign in to comment.