jsPerf.app is an online JavaScript performance benchmark test runner & jsperf.com mirror. It is a complete rewrite in homage to the once excellent jsperf.com now with hopefully a more modern & maintainable codebase.
jsperf.com URLs are mirrored at the same path, e.g:
https://jsperf.com/negative-modulo/2
Can be accessed at:
https://jsperf.app/negative-modulo/2
const createAxisDelta = () => ({
translate: 0,
scale: 1,
origin: 0,
originPoint: 0,
})
const createDelta = () => ({
x: createAxisDelta(),
y: createAxisDelta(),
})
const treeScale = { x: 1, y: 1 }
class AxisDelta {
translate = 0
scale = 1
origin = 0
originPoint = 0
}
class Delta {
x = new AxisDelta()
y = new AxisDelta()
}
function buildProjectionTransform(
delta,
treeScale,
latestTransform
) {
let transform = ""
/**
* The translations we use to calculate are always relative to the viewport coordinate space.
* But when we apply scales, we also scale the coordinate space of an element and its children.
* For instance if we have a treeScale (the culmination of all parent scales) of 0.5 and we need
* to move an element 100 pixels, we actually need to move it 200 in within that scaled space.
*/
const xTranslate = delta.x.translate / treeScale.x
const yTranslate = delta.y.translate / treeScale.y
const zTranslate = latestTransform?.z || 0
if (xTranslate || yTranslate || zTranslate) {
transform = `translate3d(${xTranslate}px, ${yTranslate}px, ${zTranslate}px) `
}
/**
* Apply scale correction for the tree transform.
* This will apply scale to the screen-orientated axes.
*/
if (treeScale.x !== 1 || treeScale.y !== 1) {
transform += `scale(${1 / treeScale.x}, ${1 / treeScale.y}) `
}
if (latestTransform) {
const { transformPerspective, rotate, rotateX, rotateY, skewX, skewY } =
latestTransform
if (transformPerspective)
transform = `perspective(${transformPerspective}px) ${transform}`
if (rotate) transform += `rotate(${rotate}deg) `
if (rotateX) transform += `rotateX(${rotateX}deg) `
if (rotateY) transform += `rotateY(${rotateY}deg) `
if (skewX) transform += `skewX(${skewX}deg) `
if (skewY) transform += `skewY(${skewY}deg) `
}
/**
* Apply scale to match the size of the element to the size we want it.
* This will apply scale to the element-orientated axes.
*/
const elementScaleX = delta.x.scale * treeScale.x
const elementScaleY = delta.y.scale * treeScale.y
if (elementScaleX !== 1 || elementScaleY !== 1) {
transform += `scale(${elementScaleX}, ${elementScaleY})`
}
return transform || "none"
}
let prevTransform = ""
const prevDelta = createDelta()
const delta = createDelta()
const classDelta = new Delta()
const classPrevDelta = new Delta()
const baseAxis = createAxisDelta()
const objectDelta = {
x: Object.create(baseAxis),
y: Object.create(baseAxis)
}
const objectPrevDelta = {
x: Object.create(baseAxis),
y: Object.create(baseAxis)
}
function copyAxisDeltaInto(delta, originDelta) {
delta.translate = originDelta.translate
delta.scale = originDelta.scale
delta.originPoint = originDelta.originPoint
delta.origin = originDelta.origin
}
function copyClassAxisDeltaInto(delta, originDelta) {
delta.translate = originDelta.translate
delta.scale = originDelta.scale
delta.originPoint = originDelta.originPoint
delta.origin = originDelta.origin
}
function copyObjectAxisDeltaInto(delta, originDelta) {
delta.translate = originDelta.translate
delta.scale = originDelta.scale
delta.originPoint = originDelta.originPoint
delta.origin = originDelta.origin
}
function updateDelta() {
delta.y.scale = Math.random()
}
function updateClassDelta() {
classDelta.y.scale = Math.random()
}
function updateObjectDelta() {
objectDelta.y.scale = Math.random()
}
let transform = ""
let op = false
function hasAxisDeltaChanged(a, b) {
return (
a.translate !== b.translate ||
a.scale !== b.scale ||
a.originPoint !== b.originPoint ||
a.origin !== b.origin
)
}
function hasClassAxisDeltaChanged(a, b) {
return (
a.translate !== b.translate ||
a.scale !== b.scale ||
a.originPoint !== b.originPoint ||
a.origin !== b.origin
)
}
function hasObjectAxisDeltaChanged(a, b) {
return (
a.translate !== b.translate ||
a.scale !== b.scale ||
a.originPoint !== b.originPoint ||
a.origin !== b.origin
)
}
Ready to run.
Test | Ops/sec | |
---|---|---|
Compare string |
| ready |
Compare and copy |
| ready |
Copy class properties |
| ready |
Copy Object.create() |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.