Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
Run results for:
JSON.parse vs recursive
Go to the benchmark
Embed
Embed Benchmark Result
Run details:
User agent:
Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Mobile Safari/537.36
Browser:
Chrome Mobile 121
Operating system:
Android
Device Platform:
Mobile
Date tested:
2 years ago
Test name
Executions per second
JSON.parse
77162.5 Ops/sec
Recursive interpolate
161264.8 Ops/sec
Script Preparation code:
function isStringOrNumber(value){ return ( value !== undefined && value !== null && !Number.isNaN(value) && (typeof value === 'string' || typeof value === 'number') ); } function recursiveReplaceTemplateStrings( obj, templateDict, ignoreFieldFunc, currentPath) { if (Array.isArray(obj)) { return obj.map((item) => recursiveReplaceTemplateStrings(item, templateDict, ignoreFieldFunc, currentPath), ); } if (typeof obj === 'object' && obj !== null) { var newObj = {}; Object.keys(obj).forEach((key) => { var value = obj[key]; var keyPath = currentPath ? `${currentPath}.${key}` : key; if (typeof value !== 'string') { // Recursively call the function for non-string values newObj[key] = recursiveReplaceTemplateStrings( obj[key], templateDict, ignoreFieldFunc, keyPath, ); return; } if (!ignoreFieldFunc?.(key, currentPath)) { var regex = /\[%([^%]+)%]/g; newObj[key] = value.replace(regex, (_, dictKey) => { var actualValue = templateDict[dictKey]; return isStringOrNumber(actualValue) ? `${actualValue}` : ''; }); return; } newObj[key] = value; }); return newObj; } return obj; } function jsonReplaceTemplateStrings( obj, templateDict, ignoreFieldFunc, currentPath, ) { var jsonStr = JSON.stringify(obj, (key, value) => { if (typeof value === 'string') { if (!ignoreFieldFunc?.(key, currentPath)) { var regex = /\[%([^%]+)%]/g; return value.replace(regex, (_, dictKey) => { const actualValue = templateDict[dictKey]; return isStringOrNumber(actualValue) ? "" + actualValue : ''; }); } } return value; }); return JSON.parse(jsonStr); } var ignoreFieldFunc = (key, path) => { const nonInterpolatedFields = ['id', 'type', 'data.id']; return nonInterpolatedFields.some((val) => val === key || val === `${path}.${key}`); }; var obj = { id: 'some_id_[%some_id_part%]', type: 'flex', title: 'Hello, [%user_name%]!', data: { id: 'some_nested_id_[%some_nested_id_part%]', options: [{ id: 'some_nested_array_id_[%some_nested_array_id_part%]', text: 'option [%some_option_part%]', }, ], }, }; var templateDict = { some_id_part: 'unexpected_id_part', some_nested_id_part: 'unexpected_nested_id_part', some_nested_array_id_part: 'unexpected_nested_array_id_part', user_name: 'Jane', some_option_part: 'A', }; var expected = { id: 'some_id_[%some_id_part%]', type: 'flex', title: 'Hello, Jane!', data: { id: 'some_nested_id_[%some_nested_id_part%]', options: [{ id: 'some_nested_array_id_[%some_nested_array_id_part%]', text: 'option A' }], }, };
Tests:
JSON.parse
jsonReplaceTemplateStrings(obj, templateDict, ignoreFieldFunc)
Recursive interpolate
recursiveReplaceTemplateStrings(obj, templateDict, ignoreFieldFunc)