Skip to content

Commit 57e23f3

Browse files
Add manual v1.x tests for textToPoints()
1 parent 242337a commit 57e23f3

4 files changed

Lines changed: 158 additions & 2 deletions

File tree

contributor_docs/performance_testing.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# Performance Testing
44

5-
Performance testing is an essential part of measuring how fasst isolated code paths take to execute under a known range of conditions.
5+
Performance testing is an essential part of measuring how fast isolated code paths take to execute under a known range of conditions.
66

77
Implementation notes:
88

@@ -16,3 +16,19 @@ To isolate typography tests, run the following:
1616
```shell
1717
npx vitest bench test/bench/typography.bench.js --reporter=verbose
1818
```
19+
20+
### Manual tests on v1.x
21+
22+
These manual tests are useful to loosely check performance against v2.x as a baseline. The test harness is compatible with the one in `test/bench/typography.bench.js`.
23+
24+
To manually run typography tests against p5.js v1.x, open the following files in a browser:
25+
26+
- `textToPoints()`: `test/bench/v1_manual/text_to_points.html`
27+
28+
Note: you will need to use a [local server](https://github.com/processing/p5.js/wiki/Local-server) to avoid CORS issues when loading fonts. For example, from the root of the repo:
29+
30+
```shell
31+
npx http-server -c-1
32+
```
33+
34+
Then tests can be accessed at `http://localhost:8080/test/bench/v1_manual/text_to_points.html`.

test/bench/typography.bench.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const strs = {
1212
).join("\n") // This will hit around 15fps, 21275 points
1313
};
1414

15-
// Parameterizing test cases by function ensures consitency in test parameters across all renderers.
15+
// Parameterizing test cases by function ensures consistency in test parameters across all renderers.
1616
// Future tests should follow a similar format (e.g. TO_CONTOURS_CASES, etc)
1717
const TO_POINTS_CASES = [
1818
{label: "textToPoints() single word", str: strs.single, textSize: 20, sampleFactor: 0.5, points: 317, variance: 5, render: false},
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<html>
2+
3+
<head>
4+
<title>P5.js v1.x Typography Performance Tests</title>
5+
<meta charset='UTF-8'>
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<style>
8+
body {
9+
padding: 0;
10+
margin: 0;
11+
}
12+
13+
canvas {
14+
border: 1px solid #f0f0f0;
15+
display: block;
16+
}
17+
18+
img {
19+
border: 1px solid #fff;
20+
}
21+
22+
div {
23+
margin: 100px 0px;
24+
}
25+
26+
th, td {
27+
padding: 4px 16px;
28+
text-align: left;
29+
}
30+
</style>
31+
</head>
32+
33+
<body>
34+
<div id="results"></div>
35+
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.13/p5.js"></script>
36+
<script src="text_to_points_v1.js"></script>
37+
</body>
38+
39+
</html>
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Ensure these tests do not drift too far from ../typography.bench.js
2+
3+
const fontFile = "../../../test/manual-test-examples/type/font/LiberationSans-Bold.ttf";
4+
5+
const strs = {
6+
single: "Performance",
7+
ten: "Performance testing 10 words at a time is exhaustive! Right?",
8+
paragraph: Array.from({ length: 10 }, (_, i) =>
9+
`${i === 0 ? "\t": ""}Performance is vital in all aspects of text rendering, even 10 lines at a time. This is line ${i + 1} of 10.`
10+
).join("\n") // This will hit around 15fps, 21275 points
11+
};
12+
13+
// Parameterizing test cases by function ensures consistency in test parameters across all renderers.
14+
const TO_POINTS_CASES = [
15+
{label: "textToPoints() single word", str: strs.single, textSize: 20, sampleFactor: 0.5, points: 317, variance: 5, render: false},
16+
{label: "textToPoints() single word, 150pt", str: strs.single, textSize: 150, sampleFactor: 0.5, points: 2336, variance: 50, render: false},
17+
{label: "textToPoints() single word, with render", str: strs.single, textSize: 20, sampleFactor: 0.5, points: 317, variance: 5, render: true},
18+
{label: "textToPoints() 10 words", str: strs.ten, textSize: 20, sampleFactor: 0.5, points: 1453, variance: 5, render: false},
19+
{label: "textToPoints() paragraph", str: strs.paragraph, textSize: 20, sampleFactor: 0.5, points: 21275, variance: 50, render: false},
20+
];
21+
22+
function bootstrap(w = 400, h = 400, renderer = "p2d") {
23+
return new Promise((resolve) => {
24+
let myp5, font;
25+
new p5(function (p) {
26+
p.preload = function() {
27+
font = p.loadFont(fontFile);
28+
}
29+
p.setup = function () {
30+
myp5 = p;
31+
p.createCanvas(w, h, renderer);
32+
resolve({ myp5, font });
33+
};
34+
});
35+
});
36+
}
37+
38+
function drawPoints(myp5, points) {
39+
for (let point of points) {
40+
myp5.point(point.x, point.y);
41+
}
42+
}
43+
44+
(async function run() {
45+
let suiteName, results;
46+
47+
suiteName = "Typography v1.x: 2D";
48+
results = [];
49+
for (let testCase of TO_POINTS_CASES) {
50+
let {myp5, font} = await bootstrap();
51+
myp5.textSize(testCase.textSize);
52+
53+
let points;
54+
let duration = runTest(() => {
55+
points = font.textToPoints(testCase.str, 10, 20, testCase.textSize, { sampleFactor: testCase.sampleFactor});
56+
if (testCase.render) {
57+
drawPoints(myp5, points);
58+
}
59+
});
60+
results.push({
61+
label: testCase.label,
62+
duration: duration.toFixed(1),
63+
points: points.length,
64+
expectedPoints: testCase.points,
65+
variance: testCase.variance
66+
});
67+
myp5.remove();
68+
}
69+
writeResults(suiteName, results);
70+
71+
})();
72+
73+
function runTest(fn) {
74+
let startTime = performance.now();
75+
fn();
76+
return performance.now() - startTime;
77+
}
78+
79+
function writeResults(suiteName, results) {
80+
const container = document.getElementById("results");
81+
const table = document.createElement("table");
82+
83+
const headRow = table.createTHead().insertRow();
84+
[suiteName, "Case", "Time (ms)", "Points", "Expected Points"].forEach((cellText) => {
85+
const newCell = document.createElement("th");
86+
newCell.textContent = cellText;
87+
headRow.append(newCell);
88+
});
89+
90+
const body = table.createTBody();
91+
for (let res of results) {
92+
const row = body.insertRow();
93+
row.insertCell(); // Intentionally blank, table left-padding
94+
row.insertCell().textContent = res.label;
95+
row.insertCell().textContent = res.duration;
96+
row.insertCell().textContent = res.points;
97+
row.insertCell().textContent = `${res.expectedPoints} +/- ${res.variance}`;
98+
}
99+
100+
container.append(table);
101+
}

0 commit comments

Comments
 (0)