Skip to content

Instantly share code, notes, and snippets.

@terrysahaidak
Last active September 11, 2024 19:52
Show Gist options
  • Save terrysahaidak/6ab14bf960930609630a01dca6608aca to your computer and use it in GitHub Desktop.
Save terrysahaidak/6ab14bf960930609630a01dca6608aca to your computer and use it in GitHub Desktop.
Hermes perf benchmark
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas performance</title>
</head>
<body>
<canvas id="canvas" width="1179" height="2556"></canvas>
<div id="frametime" style="position: absolute; top: 0; left: 0; color: black; font-size: 24px; background: white; padding: 10px;">
0ms
<script>
const COUNT = 10000
const frameTimeElement = document.getElementById('frametime');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
ctx.clearRect(0, 0, width, height)
ctx.strokeStyle = 'red';
let first = null;
let frame = 0;
// Function constructor that returns a Particle
function createParticle() {
return {
next: null,
x: 0,
y: 0,
vx: 0,
vy: 0,
};
}
function prepare() {
var old;
for (var i = 0; i < COUNT; i++) {
var particle = createParticle();
particle.x = (width * Math.random()) >> 0;
particle.y = 0;
particle.vx = 0;
particle.vy = 10 * Math.random();
if (old) {
old.next = particle;
}
if (i === 0) {
first = particle;
}
old = particle;
}
}
const ctx1 = {
clearRect: (x, y, width, height) => {},
strokeRect: (x, y, width, height) => {},
save: () => {},
translate: (x, y) => {},
restore: () => {},
}
function drawLoop() {
frame++;
const frameTime = performance.now();
ctx1.clearRect(0, 0, width, height)
if (!first) {
return;
}
let particle = first;
while (particle.next) {
particle.x += particle.vx;
particle.y += particle.vy;
if (particle.x < 0) {
particle.x = width;
} else if (particle.x > width) {
particle.x = 0;
}
if (particle.y < 0) {
particle.x = height;
} else if (particle.y > height) {
particle.y = 0;
}
ctx1.save();
ctx1.translate(particle.x >> 0, particle.y >> 0);
ctx1.strokeRect(0, 0, 8, 8);
ctx1.restore();
particle = particle.next;
}
if (frame % 60 === 0) {
const time = (performance.now() - frameTime).toFixed(10);
frameTimeElement.textContent = `${COUNT} elements, frametime: ${time} ms`;
frame = 0;
}
requestAnimationFrame(drawLoop);
}
prepare();
drawLoop();
</script>
</body>
</html>
const ELEMENT_COUNT = 10000;
const FRAMES = 1000;
const dimensions = {
width: 1179,
height: 2556,
};
const white = Skia.Color("white");
const red = Skia.Color("red");
// prepare
const surface = Skia.Surface.MakeOffscreen(
dimensions.width,
dimensions.height
);
const canvas = surface.getCanvas();
const redPaint = Skia.Paint();
redPaint.setColor(red);
redPaint.setStyle(PaintStyle.Stroke);
redPaint.setStrokeWidth(1);
redPaint.setAntiAlias(true);
const rect = Skia.XYWHRect(0, 0, 8, 8);
let first: Particle | null = null;
// Function constructor that returns a Particle
function createParticle(): Particle {
return {
next: null,
x: 0,
y: 0,
vx: 0,
vy: 0,
};
}
function prepare(count: number) {
let old: Particle | null = null;
for (var i = 0; i < count; i++) {
var particle = createParticle();
particle.x = (dimensions.width * Math.random()) >> 0;
particle.y = 0;
particle.vx = 0;
particle.vy = 10 * Math.random();
if (old) {
old.next = particle;
}
if (i === 0) {
first = particle;
}
old = particle;
}
}
function drawLoop() {
canvas.clear(white);
if (!first) {
return;
}
let particle = first;
while (particle.next) {
particle.x += particle.vx;
particle.y += particle.vy;
if (particle.x < 0) {
particle.x = dimensions.width;
} else if (particle.x > dimensions.width) {
particle.x = 0;
}
if (particle.y < 0) {
particle.x = dimensions.height;
} else if (particle.y > dimensions.height) {
particle.y = 0;
}
canvas.save();
canvas.translate(particle.x >> 0, particle.y >> 0);
canvas.drawRect(rect, redPaint);
canvas.restore();
particle = particle.next;
}
surface?.flush();
}
prepare(ELEMENT_COUNT);
const start = new Date();
for (let i = 0; i < FRAMES; i++) {
drawLoop();
}
const time = new Date() - start;
console.log(time + "ms, each frame took " + time / FRAMES + "ms");
const ELEMENT_COUNT = 50000;
const FRAMES = 1000;
function bench() {
const dimensions = {
width: 1179,
height: 2556,
};
let first = null;
function createParticle() {
return {
next: null,
x: 0,
y: 0,
vx: 0,
vy: 0,
};
}
function prepare(count) {
let old = null;
for (let i = 0; i < count; i++) {
let particle = createParticle();
particle.x = (dimensions.width * Math.random()) >> 0;
particle.y = 0;
particle.vx = 0;
particle.vy = 10 * Math.random();
if (old) {
old.next = particle;
}
if (i === 0) {
first = particle;
}
old = particle;
}
}
const canvas = {
save: () => {},
translate: (x, y) => {},
drawRect: () => {},
restore: () => {},
clear: () => {},
};
function drawLoop() {
canvas.clear();
if (!first) {
return;
}
let particle = first;
while (particle.next) {
particle.x += particle.vx;
particle.y += particle.vy;
if (particle.x < 0) {
particle.x = dimensions.width;
} else if (particle.x > dimensions.width) {
particle.x = 0;
}
if (particle.y < 0) {
particle.x = dimensions.height;
} else if (particle.y > dimensions.height) {
particle.y = 0;
}
canvas.save();
canvas.translate(particle.x >> 0, particle.y >> 0);
canvas.drawRect();
canvas.restore();
particle = particle.next;
}
}
prepare(ELEMENT_COUNT);
let start = new Date().getTime();
for (var i = 0; i < FRAMES; i++) {
drawLoop();
}
const time = new Date().getTime() - start;
print(time + 'ms, each frame took ' + (time / FRAMES) + 'ms');
}
bench();
const ELEMENT_COUNT = 50000;
const FRAMES = 1000;
type IParticle = {
next: IParticle | null;
x: number;
y: number;
vx: number;
vy: number;
}
function bench() {
const dimensions = {
width: 1179,
height: 2556,
};
let first: IParticle | null = null;
// Function constructor that returns a Particle
function createParticle() {
return {
next: null,
x: 0,
y: 0,
vx: 0,
vy: 0,
};
}
function prepare(count: number) {
let old: IParticle | null = null;
for (let i = 0; i < count; i++) {
let particle = createParticle();
particle.x = (dimensions.width * Math.random()) >> 0;
particle.y = 0;
particle.vx = 0;
particle.vy = 10 * Math.random();
if (old) {
old.next = particle;
}
if (i === 0) {
first = particle;
}
old = particle;
}
}
const canvas = {
save: () => {},
translate: (x: number, y: number) => {},
drawRect: () => {},
restore: () => {},
clear: () => {},
};
function drawLoop() {
canvas.clear();
if (!first) {
return;
}
let particle = first;
while (particle.next) {
particle.x += particle.vx;
particle.y += particle.vy;
if (particle.x < 0) {
particle.x = dimensions.width;
} else if (particle.x > dimensions.width) {
particle.x = 0;
}
if (particle.y < 0) {
particle.x = dimensions.height;
} else if (particle.y > dimensions.height) {
particle.y = 0;
}
canvas.save();
canvas.translate(particle.x >> 0, particle.y >> 0);
canvas.drawRect();
canvas.restore();
particle = particle.next;
}
}
prepare(ELEMENT_COUNT);
let start = new Date().getTime();
for (var i = 0; i < FRAMES; i++) {
drawLoop();
}
var time = new Date().getTime() - start;
print(time + 'ms, each frame took ' + (time / FRAMES) + 'ms');
}
bench();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment