<!--your preparation HTML code goes here-->
/*your preparation JavaScript code goes here
To execute async code during the script preparation, wrap it as function globalMeasureThatScriptPrepareFunction, example:*/
async function globalMeasureThatScriptPrepareFunction() {
// This function is optional, feel free to remove it.
// await someThing();
}
const gameSceneObject = {
id: "test-scene-1",
version: 1.2,
settings: {
gravity: [0, -9.81, 0],
ambientLight: {
color: 0x404040,
intensity: 0.5
},
physicsIterations: 6,
maxEntities: 1000
},
entities: [
{
id: "ground",
transform: {
position: [0, -0.5, 0],
rotation: [0, 0, 0, 1], // Quaternion
scale: [1, 1, 1]
},
components: {
geometry: {
type: "box",
width: 100,
height: 1,
depth: 100
},
material: {
type: "standard",
color: 0x808080,
roughness: 0.8,
metalness: 0.2,
map: null
},
physics: {
type: "static",
mass: 0,
colliders: [
{
type: "box",
width: 100,
height: 1,
depth: 100,
offset: [0, 0, 0]
}
]
},
tags: ["ground", "static", "environment"]
}
},
// Multiple dynamic objects
Array(50).fill(0).map((_, i) => ({
id: `dynamic-box-${i}`,
transform: {
position: [
Math.sin(i * 0.1) * 20,
5 + (i % 10),
Math.cos(i * 0.1) * 20
],
rotation: [Math.random(), Math.random(), Math.random(), Math.random()],
scale: [1, 1, 1]
},
components: {
geometry: {
type: "box",
width: 1 + Math.random(),
height: 1 + Math.random(),
depth: 1 + Math.random()
},
material: {
type: "standard",
color: Math.floor(Math.random() * 0xFFFFFF),
roughness: Math.random(),
metalness: Math.random(),
map: null
},
physics: {
type: "dynamic",
mass: 1 + Math.random() * 10,
linearDamping: 0.01,
angularDamping: 0.01,
colliders: [
{
type: "box",
width: 1 + Math.random(),
height: 1 + Math.random(),
depth: 1 + Math.random(),
offset: [0, 0, 0]
}
]
},
tags: ["dynamic", "interactive", i % 2 === 0 ? "group-a" : "group-b"]
}
})),
// Character
{
id: "player",
transform: {
position: [0, 2, 0],
rotation: [0, 0, 0, 1],
scale: [1, 1, 1]
},
components: {
geometry: {
type: "capsule",
radius: 0.5,
height: 1.5
},
material: {
type: "standard",
color: 0x3366FF,
roughness: 0.5,
metalness: 0.2
},
physics: {
type: "kinematic",
mass: 70,
colliders: [
{
type: "capsule",
radius: 0.5,
height: 1.5,
offset: [0, 0, 0]
}
],
controller: {
type: "character",
jumpHeight: 2.0,
movementSpeed: 5.0,
turnSpeed: 120
}
},
tags: ["player", "character", "controllable"],
scripts: [
{
name: "playerController",
parameters: {
maxHealth: 100,
stamina: 100,
abilities: ["jump", "sprint", "interact"]
}
}
]
}
}
],
lights: [
{
type: "directional",
intensity: 1.0,
color: 0xFFFFFF,
position: [10, 20, 10],
castShadow: true,
shadowMapSize: 2048
},
{
type: "point",
intensity: 0.8,
color: 0xFF9900,
position: [-5, 3, 2],
distance: 15,
decay: 2
}
],
metadata: {
name: "Test Scene",
author: "Engine Developer",
createdAt: "2025-03-27T10:15:30Z",
tags: ["test", "benchmark", "development"],
custom: {
difficulty: "medium",
timeLimit: 300,
objectives: [
{ id: "obj1", description: "Collect all items", completed: false },
{ id: "obj2", description: "Reach the exit", completed: false }
]
}
}
};
JSON.stringify(gameSceneObject);
const gameConfiguration = {
version: "1.5.0",
engine: {
physics: {
gravity: [0, -9.81, 0],
timeStep: 1/60,
solverIterations: 8,
collisionGroups: {
default: 1,
static: 2,
dynamic: 4,
character: 8,
sensor: 16,
projectile: 32
},
collisionMatrix: {
"1": 63, // default collides with everything
"2": 61, // static collides with everything except static
"4": 59, // dynamic collides with everything except dynamic
"8": 39, // character collides with default, static, dynamic, projectile
"16": 7, // sensor collides with default, static, dynamic
"32": 11 // projectile collides with default, static, character
}
},
rendering: {
resolution: [1920, 1080],
shadows: {
enabled: true,
type: "PCF",
resolution: 2048,
bias: 0.0005,
darkness: 0.5,
mapSize: 4096
},
postProcessing: {
enabled: true,
effects: {
bloom: {
enabled: true,
threshold: 0.8,
intensity: 0.5,
radius: 0.75
},
ssao: {
enabled: true,
radius: 0.1,
minDistance: 0.0001,
maxDistance: 0.1,
intensity: 1.5
},
toneMappingSettings: {
exposure: 1.0,
whitePoint: 1.0,
type: "ACES"
}
}
}
},
audio: {
channels: 32,
spatialAudio: true,
reverb: {
enabled: true,
presets: {
"bathroom": { decay: 1.5, damping: 0.25, spread: 0.5 },
"hallway": { decay: 2.5, damping: 0.4, spread: 0.8 },
"cave": { decay: 4.0, damping: 0.2, spread: 0.9 },
"cathedral": { decay: 6.0, damping: 0.1, spread: 0.95 }
}
}
}
},
defaultScene: {
ambientLight: {
color: 0x334455,
intensity: 0.2
},
directionalLight: {
color: 0xFFFFEE,
intensity: 1.2,
position: [50, 200, 100],
castShadow: true
},
environment: {
skybox: "default_sky",
fog: {
enabled: true,
color: 0xAACCFF,
near: 10,
far: 1000
}
},
camera: {
fov: 75,
near: 0.1,
far: 2000,
defaultPosition: [0, 5, 10],
defaultTarget: [0, 0, 0]
}
},
defaultTemplates: {
player: {
components: {
transform: {
position: [0, 1, 0],
rotation: [0, 0, 0, 1],
scale: [1, 1, 1]
},
model: {
mesh: "character_base",
materials: {
body: "character_material",
head: "head_material",
feet: "boots_material"
}
},
physics: {
type: "character",
mass: 70,
height: 1.8,
radius: 0.35,
stepHeight: 0.35,
jumpForce: 8
},
input: {
type: "humanoid",
moveSpeed: 5,
sprintMultiplier: 1.5,
turnSpeed: 180,
jumpCooldown: 0.3,
airControl: 0.3
},
health: {
max: 100,
current: 100,
regenRate: 1,
regenDelay: 5
},
inventory: {
slots: 20,
startingItems: [
{ id: "health_potion", count: 3 },
{ id: "basic_sword", count: 1, equipped: true },
{ id: "leather_armor", count: 1, equipped: true }
]
}
}
},
enemy: {
components: {
transform: {
position: [0, 0, 0],
rotation: [0, 0, 0, 1],
scale: [1, 1, 1]
},
model: {
mesh: "enemy_base",
materials: {
body: "enemy_material"
}
},
physics: {
type: "character",
mass: 80,
height: 2.0,
radius: 0.4,
stepHeight: 0.4
},
ai: {
type: "patrol",
detectionRadius: 15,
attackRange: 2,
patrolPath: [
[10, 0, 10],
[10, 0, -10],
[-10, 0, -10],
[-10, 0, 10]
],
behavior: {
idle: { duration: [2, 5], probability: 0.2 },
patrol: { speed: 2, probability: 0.6 },
chase: { speed: 5, maxDuration: 10 },
attack: { damage: 10, cooldown: 1.5, animations: ["attack1", "attack2"] }
}
},
health: {
max: 120,
current: 120,
regenRate: 0.5,
regenDelay: 10
}
}
},
item: {
components: {
transform: {
position: [0, 0, 0],
rotation: [0, 0, 0, 1],
scale: [1, 1, 1]
},
model: {
mesh: "item_pickup",
materials: {
base: "item_material"
}
},
physics: {
type: "dynamic",
mass: 5,
shape: "box",
dimensions: [0.5, 0.5, 0.5]
},
interaction: {
type: "pickup",
prompt: "Press E to pick up",
radius: 1.5,
highlightColor: 0xFFFF00
}
}
}
},
userPreferences: {
graphics: {
quality: "high",
antialiasing: "TAA",
shadows: "medium",
textures: "high",
effects: "medium",
vsync: true,
fov: 75
},
audio: {
master: 0.8,
music: 0.6,
sfx: 0.9,
voice: 1.0,
ambient: 0.7
},
gameplay: {
difficulty: "normal",
tutorials: true,
invertY: false,
autoAim: false,
cameraShake: true,
damageFeedback: true,
language: "en",
subtitles: false
},
controls: {
keyboard: {
moveForward: "W",
moveBackward: "S",
moveLeft: "A",
moveRight: "D",
jump: "Space",
sprint: "Shift",
interact: "E",
inventory: "I",
pause: "Escape",
attack: "Mouse0",
block: "Mouse1",
ability1: "Q",
ability2: "F",
ability3: "R"
},
gamepad: {
invertXAxis: false,
invertYAxis: false,
vibration: true,
deadzone: 0.1,
sensitivity: 0.8
},
mouse: {
sensitivity: 0.5,
smoothing: 0.2,
acceleration: false
}
}
}
};
JSON.stringify(gameConfiguration);
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
gmae object | |
second |
Test name | Executions per second |
---|---|
gmae object | 9068.3 Ops/sec |
second | 116976.9 Ops/sec |
The benchmark defined here is focused on evaluating the performance of JSON.stringify()
on two different complex JavaScript objects simulating game scenes in a typical game engine structure.
1. Structure Being Tested:
2. JavaScript Feature Used:
JSON.stringify()
, which converts a JavaScript object into a JSON string representation. This method is crucial in scenarios where data needs to be serialized for storage or transmission over a network.gameSceneObject
gameConfiguration
The benchmark results provide insights into the executions per second for each test case:
gameConfiguration
object, there were around 116,976.86 executions per second.gameSceneObject
showed much lower performance at approximately 9,068.32 executions per second.Complexity and Structure:
JSON.stringify()
. Optimizing data structures to limit nesting or unnecessary data can improve performance.Data Manipulation Libraries:
Custom Serialization Logic:
toJSON()
method for objects can provide a more controlled way to serialize only the necessary components of an object, thus potentially speeding up the process.Caching Mechanisms:
Using Alternative Formats:
'Protocol Buffers'
, 'MessagePack'
, or other binary serialization formats can provide more compact representations than JSON, reducing serialization time and size compared to JSON, albeit with a trade-off in human-readability.This benchmark serves as a crucial demonstration of how object complexity impacts JavaScript performance concerning JSON serialization. Through evaluating different structures, engineers can better understand the trade-offs and make informed choices depending on the requirements of their applications. When dealing with complex objects, especially in game development, it's essential to weigh the trade-offs between clarity and performance.