mirror of
https://github.com/servo/servo.git
synced 2025-09-12 07:58:20 +01:00
tests: Vendor blink perf tests (#38654)
Vendors the [blink perf tests](https://chromium.googlesource.com/chromium/src/+/HEAD/third_party/blink/perf_tests/). These perf tests are useful to evaluate the performance of servo. The license that governs the perf tests is included in the folder. Running benchmark cases automatically is left to future work. The update.py script is taken from mozjs and slightly adapted, so we can easily filter (and patch if this should be necessary in the future. Testing: This PR just adds the perf_tests, but does not use or modify them in any way. --------- Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
This commit is contained in:
parent
7621332824
commit
ee781b71b4
648 changed files with 359694 additions and 0 deletions
1
tests/blink_perf_tests/perf_tests/dom/DIR_METADATA
Normal file
1
tests/blink_perf_tests/perf_tests/dom/DIR_METADATA
Normal file
|
@ -0,0 +1 @@
|
|||
mixins: "//third_party/blink/renderer/core/dom/COMMON_METADATA"
|
1
tests/blink_perf_tests/perf_tests/dom/OWNERS
Normal file
1
tests/blink_perf_tests/perf_tests/dom/OWNERS
Normal file
|
@ -0,0 +1 @@
|
|||
file://third_party/blink/renderer/core/dom/OWNERS
|
|
@ -0,0 +1,23 @@
|
|||
<!doctype html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
|
||||
<div id="container"></div>
|
||||
|
||||
<script>
|
||||
const formCount = 1000;
|
||||
const forms = {}
|
||||
const container = document.getElementById("container")
|
||||
for (let i = 0; i < formCount; i++) {
|
||||
container.insertAdjacentHTML("beforeend",
|
||||
`<form id="form-${i}"></form>`)
|
||||
const form = document.getElementById(`form-${i}`)
|
||||
forms[form.id] = form;
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: 'Measure the speed of cloning body containing form elements inserted into a collection',
|
||||
run: () => {
|
||||
document.body.cloneNode(true);
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,28 @@
|
|||
<script src="../resources/runner.js"></script>
|
||||
|
||||
<div id="holder"></div>
|
||||
|
||||
<script>
|
||||
const holderElement = document.getElementById("holder");
|
||||
customElements.define('my-element', class MyElement extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
const shadowRoot = this.attachShadow({mode: 'open'});
|
||||
shadowRoot.innerHTML = '<style>:host { color: red; }</style>';
|
||||
}
|
||||
});
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of styling custom elements with shadowRoot's innerHTML.",
|
||||
|
||||
run: function() {
|
||||
holderElement.textContent = '';
|
||||
for (i = 0; i < 100; i++) {
|
||||
holderElement.appendChild(document.createElement('my-element'));
|
||||
// force layout.
|
||||
document.body.offsetWidth;
|
||||
}
|
||||
},
|
||||
warmUpCount: 1,
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,30 @@
|
|||
<script src="../resources/runner.js"></script>
|
||||
|
||||
<div id="holder"></div>
|
||||
|
||||
<script>
|
||||
const holderElement = document.getElementById("holder");
|
||||
|
||||
const constructedStyleSheet = new CSSStyleSheet();
|
||||
constructedStyleSheet.insertRule("* { color: red; }");
|
||||
window.customElements.define("element-constructed", class extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}, { style: constructedStyleSheet });
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: "Measures performance of styling custom elements with default style.",
|
||||
|
||||
run: function() {
|
||||
holderElement.textContent = '';
|
||||
for (i = 0; i < 100; i++) {
|
||||
holderElement.appendChild(document.createElement('element-constructed'));
|
||||
// force layout.
|
||||
document.body.offsetWidth;
|
||||
}
|
||||
},
|
||||
|
||||
warmUpCount: 1,
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
<style>
|
||||
select, ::picker(select) {
|
||||
appearance: base-select;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<select id="container"></select>
|
||||
<script>
|
||||
var container = document.getElementById('container');
|
||||
var nodes = [];
|
||||
var childCount = 500;
|
||||
for (var i = 0; i < childCount; ++i)
|
||||
nodes.push(document.createElement('option'));
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: 'Measures performance of adding option elements to a single-selection select element.',
|
||||
run: function() {
|
||||
for (var i = 0; i < childCount; ++i) {
|
||||
nodes[i].selected = !!(i % 2);
|
||||
container.appendChild(nodes[i]);
|
||||
}
|
||||
container.innerHTML = '';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<style>
|
||||
select, ::picker(select) {
|
||||
appearance: base-select;
|
||||
}
|
||||
</style>
|
||||
<select id="container"></select>
|
||||
<script>
|
||||
var container = document.getElementById('container');
|
||||
var nodes = [];
|
||||
var childCount = 1000;
|
||||
for (var i = 0; i < childCount; ++i) {
|
||||
var option = document.createElement('option');
|
||||
option.textContent = i;
|
||||
nodes.push(option);
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: 'Measures performance of removing option elements from a single-selection select element.',
|
||||
|
||||
run: () => {
|
||||
for (var i = 0; i < childCount; ++i) {
|
||||
nodes[i].selected = false;
|
||||
container.appendChild(nodes[i]);
|
||||
}
|
||||
container.offsetLeft;
|
||||
for (var i = 0; i < childCount; ++i)
|
||||
container.removeChild(nodes[i]);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
|
||||
<div id="source" style="display:none">
|
||||
<div></div>
|
||||
</div>
|
||||
<div id="destination" style="display:none"></div>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
var sourceEl = document.getElementById('source').firstElementChild;
|
||||
var destinationEl = document.getElementById('destination');
|
||||
|
||||
function buildTree(depth,parent) {
|
||||
while (depth--) {
|
||||
parent = parent.appendChild(document.createElement('span'));
|
||||
}
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: 'Measure the speed of cloning and appending a very deep tree',
|
||||
setup: () => {
|
||||
const treeDepth = 10000;
|
||||
if (!sourceEl.childNodes.length) {
|
||||
sourceEl.replaceChildren();
|
||||
buildTree(treeDepth, sourceEl);
|
||||
PerfTestRunner.assert_true(sourceEl.querySelectorAll('span').length === treeDepth,'Tree depth mismatch');
|
||||
}
|
||||
destinationEl.replaceChildren();
|
||||
PerfTestRunner.gc();
|
||||
},
|
||||
run: () => {
|
||||
destinationEl.appendChild(sourceEl.cloneNode(true));
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/dom-parts-api.js"></script>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
runPerfTest('Parts, flat','appendTime');
|
||||
</script>
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/dom-parts-api.js"></script>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
runPerfTest('Parts, flat','cloneTime');
|
||||
</script>
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/dom-parts-api.js"></script>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
runPerfTest('Parts, flat','getPartsTime');
|
||||
</script>
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/dom-parts-api.js"></script>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
runPerfTest('Manual tree walk','appendTime');
|
||||
</script>
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/dom-parts-api.js"></script>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
runPerfTest('Manual tree walk','cloneTime');
|
||||
</script>
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/dom-parts-api.js"></script>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
runPerfTest('Manual tree walk','getPartsTime');
|
||||
</script>
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/dom-parts-api.js"></script>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
runPerfTest('Parts, nested','appendTime');
|
||||
</script>
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/dom-parts-api.js"></script>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
runPerfTest('Parts, nested','cloneTime');
|
||||
</script>
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script src="resources/dom-parts-api.js"></script>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
runPerfTest('Parts, nested','getPartsTime');
|
||||
</script>
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<div id="container" dir="auto"></div>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
container.style.display = 'none';
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: 'Measures performance of inserting a text node' +
|
||||
'as a child of an element having dir=auto attribute',
|
||||
setup() {
|
||||
container.innerHTML = "";
|
||||
},
|
||||
run() {
|
||||
for (var i = 0; i < 10000; i++)
|
||||
container.appendChild(document.createTextNode('a'));
|
||||
}
|
||||
});
|
||||
</script>
|
27
tests/blink_perf_tests/perf_tests/dom/long-sibling-list.html
Normal file
27
tests/blink_perf_tests/perf_tests/dom/long-sibling-list.html
Normal file
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<div id="container"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
PerfTestRunner.assert_true(typeof window.GCController !== "undefined", 'GCController is required for accurate measurement');
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: 'Adds, then lays out, a long list of sibling elements ' +
|
||||
'separated by spaces',
|
||||
setup: () => {
|
||||
container.parentNode.replaceChild(container.cloneNode(false), container);
|
||||
PerfTestRunner.gc();
|
||||
},
|
||||
run: () => {
|
||||
const num_words = 30000;
|
||||
for (var i = 0; i < num_words; i++) {
|
||||
var a = document.createElement('a');
|
||||
a.appendChild(document.createTextNode('' + i));
|
||||
container.appendChild(a);
|
||||
container.appendChild(document.createTextNode(' '));
|
||||
}
|
||||
PerfTestRunner.forceLayout();
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script>
|
||||
var element;
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures performance of changing a DOM element's className property.",
|
||||
|
||||
setup: function() {
|
||||
element = document.createElement('div');
|
||||
},
|
||||
|
||||
run: function() {
|
||||
for (var i = 0; i < 500000; ++i) {
|
||||
element.className = 'class1';
|
||||
element.className = 'class2';
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
24
tests/blink_perf_tests/perf_tests/dom/modify-element-id.html
Normal file
24
tests/blink_perf_tests/perf_tests/dom/modify-element-id.html
Normal file
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script>
|
||||
var element;
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures performance of changing a DOM element's id property.",
|
||||
|
||||
setup: function() {
|
||||
element = document.createElement('div');
|
||||
},
|
||||
|
||||
run: function() {
|
||||
for (var i = 0; i < 500000; ++i) {
|
||||
element.id = 'id1';
|
||||
element.id = 'id2';
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<script>
|
||||
var element;
|
||||
|
||||
PerfTestRunner.measureTime({
|
||||
description: "Measures performance of changing a DOM element's title property.",
|
||||
|
||||
setup: function() {
|
||||
element = document.createElement('div');
|
||||
},
|
||||
|
||||
run: function() {
|
||||
for (var i = 0; i < 500000; ++i) {
|
||||
element.title = 'title1';
|
||||
element.title = 'title2';
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<div id="container" dir="auto"></div>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
container.style.display = 'none';
|
||||
|
||||
var textNode = document.createTextNode('a');
|
||||
container.appendChild(textNode);
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: 'Measures performance of changing a text data of the child' +
|
||||
'in an element having dir=auto attribute ',
|
||||
run() {
|
||||
for (var i = 0; i < 10000; i++) {
|
||||
textNode.replaceData(0, 1, "b");
|
||||
textNode.replaceData(0, 1, "a");
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
268
tests/blink_perf_tests/perf_tests/dom/resources/dom-parts-api.js
Normal file
268
tests/blink_perf_tests/perf_tests/dom/resources/dom-parts-api.js
Normal file
|
@ -0,0 +1,268 @@
|
|||
(() => {
|
||||
// Creates width <section> elements surrounded (optionally) by ChildNodeParts.
|
||||
// Each <section> gets width children of the same kind, down to a depth of depth.
|
||||
// If useParts is false, no Parts are constructed. If useParts is true, and
|
||||
// chainParts is true, descendant Parts use ancestor Parts as their PartRoot.
|
||||
// If chainParts is false, all Parts have the DocumentPartRoot as their root.
|
||||
const createContent = (node, root, useParts, chainParts, width, depth, extra, at = 0) => {
|
||||
at++;
|
||||
for (let i=0; i<width; i++) {
|
||||
const s = document.createComment('start');
|
||||
const c = document.createElement('section');
|
||||
c.textContent = `${at}.${i}`;
|
||||
let extras = [];
|
||||
for(let e=0;e<extra;e++) {
|
||||
extras.push(Object.assign(document.createElement('span'),{classList:'extra'}));
|
||||
}
|
||||
if (i==0) {
|
||||
const nodePartNode = document.createElement('section');
|
||||
nodePartNode.textContent = 'nodepart';
|
||||
extras.push(nodePartNode);
|
||||
if (useParts) {
|
||||
new NodePart(root, nodePartNode);
|
||||
}
|
||||
}
|
||||
const e = document.createComment('e');
|
||||
node.append(s, c, ...extras, e);
|
||||
let nextLevelRoot = root;
|
||||
if (useParts) {
|
||||
const newPart = new ChildNodePart(root, s, e);
|
||||
if (chainParts) {
|
||||
nextLevelRoot = newPart;
|
||||
}
|
||||
}
|
||||
if (at < depth) {
|
||||
createContent(c, nextLevelRoot, useParts, chainParts, width, depth, extra, at);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const createTemplateWrapper = () => {
|
||||
const template = document.createElement('template').content;
|
||||
const wrapper = template.appendChild(document.createElement('div'));
|
||||
return {template,wrapper};
|
||||
}
|
||||
let commentContent,partsFlatContent,partsNestedContent;
|
||||
let contentCreated = false;
|
||||
function createAllContent(width, depth, extra) {
|
||||
contentCreated = true;
|
||||
commentContent = createTemplateWrapper();
|
||||
createContent(commentContent.wrapper, commentContent.template.getPartRoot(), /*useParts*/false, 0, width, depth, extra);
|
||||
|
||||
partsFlatContent = createTemplateWrapper();
|
||||
createContent(partsFlatContent.wrapper, partsFlatContent.template.getPartRoot(), /*useParts*/true, /*chainParts*/false, width, depth, extra);
|
||||
|
||||
partsNestedContent = createTemplateWrapper();
|
||||
createContent(partsNestedContent.wrapper, partsNestedContent.template.getPartRoot(), /*useParts*/true, /*chainParts*/true, width, depth, extra);
|
||||
}
|
||||
|
||||
|
||||
const errorCheck = (container) => {
|
||||
if (!contentCreated) {
|
||||
throw new Error('content must be created with createAllContent()');
|
||||
}
|
||||
if (!container.isConnected || container.ownerDocument != document) {
|
||||
throw new Error('container must be in the document');
|
||||
}
|
||||
if (container.childNodes.length !== 0) {
|
||||
throw new Error('container must be empty');
|
||||
}
|
||||
if (document.getPartRoot().getParts().length !== 0) {
|
||||
throw new Error('test needs to start with no attached parts');
|
||||
}
|
||||
return {container};
|
||||
}
|
||||
|
||||
const recursiveGetParts = (root,level=1) => {
|
||||
let parts = Array.from(root.getParts());
|
||||
const thisParts = [...parts];
|
||||
for(let part of thisParts) {
|
||||
if (part.getParts) {
|
||||
parts.push(...recursiveGetParts(part,level+1));
|
||||
}
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
const countNodes = (node) => {
|
||||
let c = 1;
|
||||
node.childNodes.forEach(child => {
|
||||
c += countNodes(child);
|
||||
});
|
||||
return c;
|
||||
}
|
||||
|
||||
const countNodesAndParts = (state) => {
|
||||
const nodes = countNodes(state.container);
|
||||
const root = state.container.ownerDocument.getPartRoot();
|
||||
let parts,nodeParts,childNodeParts;
|
||||
if (!root.getParts().length) {
|
||||
partCount = state.parts.length;
|
||||
nodeParts = state.parts.filter(p => p instanceof FakeNodePart).length;
|
||||
childNodeParts = state.parts.filter(p => p instanceof FakeChildNodePart).length;
|
||||
} else {
|
||||
const parts = recursiveGetParts(root);
|
||||
partCount = parts.length;
|
||||
nodeParts = parts.filter(p => p instanceof NodePart).length;
|
||||
childNodeParts = parts.filter(p => p instanceof ChildNodePart).length;
|
||||
}
|
||||
return {nodes, partCount, nodeParts, childNodeParts};
|
||||
}
|
||||
|
||||
class FakeChildNodePart {
|
||||
start = null;
|
||||
end = null;
|
||||
constructor(start, end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
}
|
||||
class FakeNodePart {
|
||||
node = null;
|
||||
constructor(node) {
|
||||
this.node = node;
|
||||
}
|
||||
}
|
||||
|
||||
const testList = [
|
||||
{
|
||||
test: "Raw, no parts",
|
||||
prepare: (container) => errorCheck(container),
|
||||
clone: (state) => {
|
||||
state.clone = document.importNode(commentContent.template, true);
|
||||
},
|
||||
append: (state) => {
|
||||
state.container.appendChild(state.clone);
|
||||
},
|
||||
getParts: (state) => {
|
||||
state.parts = [];
|
||||
},
|
||||
},
|
||||
{
|
||||
test: "Manual tree walk",
|
||||
prepare: (container) => {
|
||||
state = errorCheck(container);
|
||||
state.walker = document.createTreeWalker(document, 129 /* NodeFilter.SHOW_{ELEMENT|COMMENT} */);
|
||||
return state;
|
||||
},
|
||||
clone: (state) => {
|
||||
state.clone = document.importNode(commentContent.template, true);
|
||||
},
|
||||
append: (state) => {
|
||||
state.container.appendChild(state.clone);
|
||||
},
|
||||
getParts: (state) => {
|
||||
const parts = [];
|
||||
state.walker.currentNode = state.container;
|
||||
while (state.walker.nextNode()) {
|
||||
const node = state.walker.currentNode;
|
||||
if (node.nodeType === Node.COMMENT_NODE && node.textContent === 'start') {
|
||||
parts.push(new FakeChildNodePart(node,node.nextSibling.nextSibling));
|
||||
} else if (node.nodeType === Node.ELEMENT_NODE && node.firstChild?.nodeType === Node.TEXT_NODE && node.firstChild.textContent === 'nodepart') {
|
||||
parts.push(new FakeNodePart(node));
|
||||
}
|
||||
}
|
||||
state.parts = parts;
|
||||
},
|
||||
},
|
||||
{
|
||||
test: "Parts, flat",
|
||||
prepare: (container) => errorCheck(container),
|
||||
clone: (state) => {
|
||||
state.clone = partsFlatContent.template.getPartRoot().clone().rootContainer;
|
||||
},
|
||||
append: (state) => {
|
||||
state.container.appendChild(state.clone);
|
||||
},
|
||||
getParts: (state) => {
|
||||
state.parts = document.getPartRoot().getParts();
|
||||
},
|
||||
},
|
||||
{
|
||||
test: "Parts, nested",
|
||||
prepare: (container) => errorCheck(container),
|
||||
clone: (state) => {
|
||||
state.clone = partsNestedContent.template.getPartRoot().clone().rootContainer;
|
||||
},
|
||||
append: (state) => {
|
||||
state.container.appendChild(state.clone);
|
||||
},
|
||||
getParts: (state) => {
|
||||
state.parts = recursiveGetParts(document.getPartRoot());
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const runTest = (testCase, repeats, container) => {
|
||||
let cloneTime = 0;
|
||||
let appendTime = 0;
|
||||
let getPartsTime = 0;
|
||||
let state;
|
||||
for(let r=0;r<repeats;++r) {
|
||||
// Clear out the old parts and content:
|
||||
container.replaceChildren();
|
||||
document.getPartRoot().getParts();
|
||||
if (typeof window.GCController !== "undefined") {
|
||||
// PerfTestRunner is providing GC.
|
||||
PerfTestRunner.gc();
|
||||
} else if (self.gc) {
|
||||
// This requires --js-flags="--expose-gc" on the command line.
|
||||
self.gc();
|
||||
} else {
|
||||
PerfTestRunner.assert_true(false,'This test requires some form of GC access');
|
||||
}
|
||||
state = testCase.prepare(container);
|
||||
// Run the test
|
||||
const start = performance.now();
|
||||
testCase.clone(state);
|
||||
const cloneDone = performance.now();
|
||||
testCase.append(state);
|
||||
const appendDone = performance.now();
|
||||
testCase.getParts(state);
|
||||
const partsDone = performance.now();
|
||||
cloneTime += cloneDone - start;
|
||||
appendTime += appendDone - cloneDone;
|
||||
getPartsTime += partsDone - appendDone;
|
||||
}
|
||||
return {cloneTime, appendTime, getPartsTime, state};
|
||||
}
|
||||
|
||||
const findTestCase = (testType) => {
|
||||
const indx = testList.findIndex(v => v.test == testType);
|
||||
PerfTestRunner.assert_true(indx >= 0,`Unable to find test for ${testType}`);
|
||||
return testList[indx];
|
||||
}
|
||||
|
||||
const runPerfTest = (testType,metric) => {
|
||||
const width = 4;
|
||||
const depth = 4;
|
||||
const extra = 8;
|
||||
const repeats = 10;
|
||||
const container = document.createElement('div');
|
||||
container.style="display:none";
|
||||
document.body.appendChild(container);
|
||||
PerfTestRunner.measureValue({
|
||||
description: `This benchmark tests the ${metric} time for ${testType}, for the DOM Parts API`,
|
||||
unit: 'ms',
|
||||
setup: () => {
|
||||
createAllContent(width, depth, extra);
|
||||
},
|
||||
run: function() {
|
||||
const results = runTest(findTestCase(testType), repeats, container);
|
||||
return results[metric];
|
||||
},
|
||||
warmUpCount: 2,
|
||||
iterationCount: 30,
|
||||
});
|
||||
}
|
||||
|
||||
const manualRunTest = (testType, repeats, container) => {
|
||||
return runTest(findTestCase(testType), repeats, container);
|
||||
}
|
||||
|
||||
// Exposed functions:
|
||||
window.runPerfTest =runPerfTest;
|
||||
window.createAllContent = createAllContent;
|
||||
window.manualRunTest = manualRunTest;
|
||||
window.countNodesAndParts = countNodesAndParts;
|
||||
})();
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<select id="container" multiple></select>
|
||||
<script>
|
||||
var container = document.getElementById('container');
|
||||
var nodes = [];
|
||||
var childCount = 500;
|
||||
for (var i = 0; i < childCount; ++i) {
|
||||
nodes.push(document.createElement('option'));
|
||||
nodes[i].selected = !!(i % 2);
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: 'Measures performance of adding option elements to a multi-selection select element.',
|
||||
run: function() {
|
||||
for (var i = 0; i < childCount; ++i)
|
||||
container.appendChild(nodes[i]);
|
||||
container.innerHTML = '';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,62 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
<script src="../resources/runner.js"></script>
|
||||
|
||||
<button>user activation button</button>
|
||||
|
||||
<script>
|
||||
const numOptions = 3000;
|
||||
const numTestRuns = 6;
|
||||
let isDone = false;
|
||||
|
||||
const button = document.querySelector('button');
|
||||
|
||||
async function runTest() {
|
||||
while (!isDone) {
|
||||
await new Promise(requestAnimationFrame);
|
||||
await new Promise(requestAnimationFrame);
|
||||
|
||||
const select = document.createElement('select');
|
||||
for (let i = 0; i < numOptions; i++) {
|
||||
const option = document.createElement('option');
|
||||
option.textContent = i;
|
||||
select.appendChild(option);
|
||||
}
|
||||
document.body.appendChild(select);
|
||||
|
||||
// Get user activation for select.showPicker()
|
||||
await new Promise(resolve => {
|
||||
const buttonBox = button.getBoundingClientRect();
|
||||
const x = buttonBox.x + (buttonBox.width / 2);
|
||||
const y = buttonBox.y + (buttonBox.height / 2);
|
||||
chrome.gpuBenchmarking.pointerActionSequence([{
|
||||
source: 'mouse',
|
||||
actions: [
|
||||
{name: 'pointerDown', x: x, y: y},
|
||||
{name: 'pointerUp', x: x, y: y}
|
||||
]
|
||||
}], resolve);
|
||||
});
|
||||
|
||||
PerfTestRunner.addRunTestStartMarker();
|
||||
const startTime = PerfTestRunner.now();
|
||||
select.showPicker();
|
||||
|
||||
PerfTestRunner.measureValueAsync(PerfTestRunner.now() - startTime);
|
||||
PerfTestRunner.addRunTestEndMarker();
|
||||
select.remove();
|
||||
}
|
||||
}
|
||||
|
||||
PerfTestRunner.startMeasureValuesAsync({
|
||||
unit: 'ms',
|
||||
done: function() {
|
||||
isDone = true;
|
||||
},
|
||||
run: function() {
|
||||
runTest();
|
||||
},
|
||||
iterationCount: numTestRuns,
|
||||
description: "Measures performance of opening select's picker."
|
||||
});
|
||||
</script>
|
23
tests/blink_perf_tests/perf_tests/dom/select-single-add.html
Normal file
23
tests/blink_perf_tests/perf_tests/dom/select-single-add.html
Normal file
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<select id="container"></select>
|
||||
<script>
|
||||
var container = document.getElementById('container');
|
||||
var nodes = [];
|
||||
var childCount = 500;
|
||||
for (var i = 0; i < childCount; ++i)
|
||||
nodes.push(document.createElement('option'));
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: 'Measures performance of adding option elements to a single-selection select element.',
|
||||
run: function() {
|
||||
for (var i = 0; i < childCount; ++i) {
|
||||
nodes[i].selected = !!(i % 2);
|
||||
container.appendChild(nodes[i]);
|
||||
}
|
||||
container.innerHTML = '';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
<script src="../resources/runner.js"></script>
|
||||
<select id="container"></select>
|
||||
<script>
|
||||
var container = document.getElementById('container');
|
||||
var nodes = [];
|
||||
var childCount = 1000;
|
||||
for (var i = 0; i < childCount; ++i) {
|
||||
var option = document.createElement('option');
|
||||
option.textContent = i;
|
||||
nodes.push(option);
|
||||
}
|
||||
|
||||
PerfTestRunner.measureRunsPerSecond({
|
||||
description: 'Measures performance of removing option elements from a single-selection select element.',
|
||||
|
||||
run: () => {
|
||||
for (var i = 0; i < childCount; ++i) {
|
||||
nodes[i].selected = false;
|
||||
container.appendChild(nodes[i]);
|
||||
}
|
||||
container.offsetLeft;
|
||||
for (var i = 0; i < childCount; ++i)
|
||||
container.removeChild(nodes[i]);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
Loading…
Add table
Add a link
Reference in a new issue