angular/packages/zone.js/test/performance/performance_setup.js
Joey Perrott 9dbe6fc18b refactor: update license text to point to angular.dev (#57901)
Update license text to point to angular.dev instead of angular.io

PR Close #57901
2024-09-24 15:33:00 +02:00

301 lines
10 KiB
JavaScript

/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
(function (_global) {
var allTasks = _global['__zone_symbol__performance_tasks'];
if (!allTasks) {
allTasks = _global['__zone_symbol__performance_tasks'] = [];
}
var mark = (_global['__zone_symbol__mark'] = function (name) {
performance && performance['mark'] && performance['mark'](name);
});
var measure = (_global['__zone_symbol__measure'] = function (name, label) {
performance && performance['measure'] && performance['measure'](name, label);
});
var getEntries = (_global['__zone_symbol__getEntries'] = function () {
performance && performance['getEntries'] && performance['getEntries']();
});
var getEntriesByName = (_global['__zone_symbol__getEntriesByName'] = function (name) {
return performance && performance['getEntriesByName'] && performance['getEntriesByName'](name);
});
var clearMarks = (_global['__zone_symbol__clearMarks'] = function (name) {
return performance && performance['clearMarks'] && performance['clearMarks'](name);
});
var clearMeasures = (_global['__zone_symbol__clearMeasures'] = function (name) {
return performance && performance['clearMeasures'] && performance['clearMeasures'](name);
});
var averageMeasures = (_global['__zone_symbol__averageMeasures'] = function (name, times) {
var sum = _global['__zone_symbol__getEntriesByName'](name)
.filter(function (m) {
return m.entryType === 'measure';
})
.map(function (m) {
return m.duration;
})
.reduce(function (sum, d) {
return sum + d;
});
return sum / times;
});
var serialPromise = (_global['__zone_symbol__serialPromise'] = function (promiseFactories) {
let lastPromise;
for (var i = 0; i < promiseFactories.length; i++) {
var promiseFactory = promiseFactories[i];
if (!lastPromise) {
lastPromise = promiseFactory.factory(promiseFactory.context).then(function (value) {
return {value, idx: 0};
});
} else {
lastPromise = lastPromise.then(function (ctx) {
var idx = ctx.idx + 1;
var promiseFactory = promiseFactories[idx];
return promiseFactory.factory(promiseFactory.context).then(function (value) {
return {value, idx};
});
});
}
}
return lastPromise;
});
var callbackContext = (_global['__zone_symbol__callbackContext'] = {});
var zone = (_global['__zone_symbol__callbackZone'] = Zone.current.fork({
name: 'callback',
onScheduleTask: function (delegate, curr, target, task) {
delegate.scheduleTask(target, task);
if (
task.type === callbackContext.type &&
task.source.indexOf(callbackContext.source) !== -1
) {
if (task.type === 'macroTask' || task.type === 'eventTask') {
var invoke = task.invoke;
task.invoke = function () {
mark(callbackContext.measureName);
var result = invoke.apply(this, arguments);
measure(callbackContext.measureName, callbackContext.measureName);
return result;
};
} else if (task.type === 'microTask') {
var callback = task.callback;
task.callback = function () {
mark(callbackContext.measureName);
var result = callback.apply(this, arguments);
measure(callbackContext.measureName, callbackContext.measureName);
return result;
};
}
}
return task;
},
}));
var runAsync = (_global['__zone_symbol__runAsync'] = function (testFn, times, _delay) {
var delay = _delay | 100;
const fnPromise = function () {
return new Promise(function (res, rej) {
// run test with a setTimeout
// several times to decrease measurement error
setTimeout(function () {
testFn().then(function () {
res();
});
}, delay);
});
};
var promiseFactories = [];
for (var i = 0; i < times; i++) {
promiseFactories.push({factory: fnPromise, context: {}});
}
return serialPromise(promiseFactories);
});
var getNativeMethodName = function (nativeWithSymbol) {
return nativeWithSymbol.replace('__zone_symbol__', 'native_');
};
function testAddRemove(api, count) {
var timerId = [];
var name = api.method;
mark(name);
for (var i = 0; i < count; i++) {
timerId.push(api.run());
}
measure(name, name);
if (api.supportClear) {
var clearName = api.clearMethod;
mark(clearName);
for (var i = 0; i < count; i++) {
api.runClear(timerId[i]);
}
measure(clearName, clearName);
}
timerId = [];
var nativeName = getNativeMethodName(api.nativeMethod);
mark(nativeName);
for (var i = 0; i < count; i++) {
timerId.push(api.nativeRun());
}
measure(nativeName, nativeName);
if (api.supportClear) {
var nativeClearName = getNativeMethodName(api.nativeClearMethod);
mark(nativeClearName);
for (var i = 0; i < count; i++) {
api.nativeRunClear(timerId[i]);
}
measure(nativeClearName, nativeClearName);
}
return Promise.resolve(1);
}
function testCallback(api, count) {
var promises = [Promise.resolve(1)];
for (var i = 0; i < count; i++) {
var r = api.run();
if (api.isAsync) {
promises.push(r);
}
}
for (var i = 0; i < count; i++) {
var r = api.nativeRun();
if (api.isAsync) {
promises.push(r);
}
}
return Promise.all(promises);
}
function measureCallback(api, ops) {
var times = ops.times;
var displayText = ops.displayText;
var rawData = ops.rawData;
var summary = ops.summary;
var name = api.method;
var nativeName = getNativeMethodName(api.nativeMethod);
var measure = averageMeasures(name, times);
var nativeMeasure = averageMeasures(nativeName, times);
displayText += `- ${name} costs ${measure} ms\n`;
displayText += `- ${nativeName} costs ${nativeMeasure} ms\n`;
var absolute = Math.floor(1000 * (measure - nativeMeasure)) / 1000;
displayText += `# ${name} is ${absolute}ms slower than ${nativeName}\n`;
rawData[name + '_measure'] = measure;
rawData[nativeName + '_measure'] = nativeMeasure;
summary[name] = absolute + 'ms';
}
function measureAddRemove(api, ops) {
var times = ops.times;
var displayText = ops.displayText;
var rawData = ops.rawData;
var summary = ops.summary;
var name = api.method;
var nativeName = getNativeMethodName(api.nativeMethod);
var measure = averageMeasures(name, times);
var nativeMeasure = averageMeasures(nativeName, times);
displayText += `- ${name} costs ${measure} ms\n`;
displayText += `- ${nativeName} costs ${nativeMeasure} ms\n`;
var percent = Math.floor((100 * (measure - nativeMeasure)) / nativeMeasure);
displayText += `# ${name} is ${percent}% slower than ${nativeName}\n`;
rawData[name + '_measure'] = measure;
rawData[nativeName + '_measure'] = nativeMeasure;
summary[name] = percent + '%';
if (api.supportClear) {
var clearName = api.clearMethod;
var nativeClearName = getNativeMethodName(api.nativeClearMethod);
var clearMeasure = averageMeasures(clearName, times);
var nativeClearMeasure = averageMeasures(nativeClearName, times);
var clearPercent = Math.floor(
(100 * (clearMeasure - nativeClearMeasure)) / nativeClearMeasure,
);
displayText += `- ${clearName} costs ${clearMeasure} ms\n`;
displayText += `- ${nativeClearName} costs ${nativeClearMeasure} ms\n`;
displayText += `# ${clearName} is ${clearPercent}% slower than ${nativeClearName}\n`;
rawData[clearName + '_measure'] = clearMeasure;
rawData[nativeClearName + '_measure'] = nativeClearMeasure;
summary[clearName] = clearPercent + '%';
}
}
var testRunner = (_global['__zone_symbol__testRunner'] = function (testTarget) {
var title = testTarget.title;
var apis = testTarget.apis;
var methods = apis.reduce(function (acc, api) {
return acc.concat(
[api.method, api.nativeMethod].concat(
api.supportClear ? [api.clearMethod, api.nativeClearMethod] : [],
).concat[(api.method + '_callback', api.nativeMethod + '_callback')],
);
}, []);
var times = testTarget.times;
allTasks.push({
title: title,
cleanFn: function () {
methods.forEach(function (m) {
clearMarks(m);
clearMeasures(m);
});
},
before: function () {
testTarget.before && testTarget.before();
},
after: function () {
testTarget.after && testTarget.after();
},
testFn: function () {
var count = typeof testTarget.count === 'number' ? testTarget.count : 10000;
var times = typeof testTarget.times === 'number' ? testTarget.times : 5;
var testFunction = function () {
var promises = [];
apis.forEach(function (api) {
if (api.isCallback) {
var r = testCallback(api, count / 100);
promises.push(api.isAsync ? r : Promise.resolve(1));
} else {
var r = testAddRemove(api, count);
promises.push[api.isAsync ? r : Promise.resolve(1)];
}
});
return Promise.all(promises);
};
return runAsync(testFunction, times).then(function () {
var displayText = `running ${count} times\n`;
var rawData = {};
var summary = {};
apis.forEach(function (api) {
if (api.isCallback) {
measureCallback(api, {times, displayText, rawData, summary});
} else {
measureAddRemove(api, {times, displayText, rawData, summary});
}
});
return Promise.resolve({displayText: displayText, rawData: rawData, summary: summary});
});
},
});
});
})(typeof window === 'undefined' ? global : window);