يعد fast-json-stringify أسرع بكثير من JSON.stringify()
للحمولات الصغيرة. تتقلص ميزة أدائها مع نمو حمولتك. إنه يقترن بشكل جيد مع flatstr ، الذي يؤدي إلى تحسين V8 الذي يعمل على تحسين الأداء عند تحويل السلسلة في النهاية إلى Buffer
.
يتطلب fast-json-stringify إدخال JSON Schema Draft 7 لإنشاء وظيفة stringify
سريعة.
EX41S-SSD, Intel Core i7, 4Ghz, 64GB RAM, 4C/8T, SSD
.v18.12.1
FJS creation x 4,129 ops/sec ±0.82% (92 runs sampled)
CJS creation x 184,196 ops/sec ±0.12% (97 runs sampled)
AJV Serialize creation x 61,130,591 ops/sec ±0.40% (92 runs sampled)
JSON.stringify array x 5,057 ops/sec ±0.10% (100 runs sampled)
fast-json-stringify array default x 6,243 ops/sec ±0.14% (98 runs sampled)
fast-json-stringify array json-stringify x 6,261 ops/sec ±0.30% (99 runs sampled)
compile-json-stringify array x 6,842 ops/sec ±0.18% (96 runs sampled)
AJV Serialize array x 6,964 ops/sec ±0.11% (95 runs sampled)
JSON.stringify large array x 248 ops/sec ±0.07% (90 runs sampled)
fast-json-stringify large array default x 99.96 ops/sec ±0.22% (74 runs sampled)
fast-json-stringify large array json-stringify x 248 ops/sec ±0.07% (90 runs sampled)
compile-json-stringify large array x 317 ops/sec ±0.09% (89 runs sampled)
AJV Serialize large array x 111 ops/sec ±0.07% (33 runs sampled)
JSON.stringify long string x 16,002 ops/sec ±0.09% (98 runs sampled)
fast-json-stringify long string x 15,979 ops/sec ±0.09% (96 runs sampled)
compile-json-stringify long string x 15,952 ops/sec ±0.31% (97 runs sampled)
AJV Serialize long string x 21,416 ops/sec ±0.08% (98 runs sampled)
JSON.stringify short string x 12,944,272 ops/sec ±0.09% (96 runs sampled)
fast-json-stringify short string x 30,585,790 ops/sec ±0.27% (97 runs sampled)
compile-json-stringify short string x 30,656,406 ops/sec ±0.12% (96 runs sampled)
AJV Serialize short string x 30,406,785 ops/sec ±0.37% (96 runs sampled)
JSON.stringify obj x 3,153,043 ops/sec ±0.33% (99 runs sampled)
fast-json-stringify obj x 6,866,434 ops/sec ±0.11% (100 runs sampled)
compile-json-stringify obj x 15,886,723 ops/sec ±0.15% (98 runs sampled)
AJV Serialize obj x 8,969,043 ops/sec ±0.36% (97 runs sampled)
JSON stringify date x 1,126,547 ops/sec ±0.09% (97 runs sampled)
fast-json-stringify date format x 1,836,188 ops/sec ±0.12% (99 runs sampled)
compile-json-stringify date format x 1,125,735 ops/sec ±0.19% (98 runs sampled)
Example
Options
API
fastJsonStringify
Specific use cases
Required
Missing fields
Pattern Properties
Additional Properties
AnyOf
وواحد OneOf
Reuse - $ref
Long integers
Integers
Nullable
Large Arrays
Security Notice
Debug Mode
Standalone Mode
Acknowledgements
License
جربه على RunKit: https://runkit.com/npm/fast-json-stringify
const fastJson = require ( 'fast-json-stringify' )
const stringify = fastJson ( {
title : 'Example Schema' ,
type : 'object' ,
properties : {
firstName : {
type : 'string'
} ,
lastName : {
type : 'string'
} ,
age : {
description : 'Age in years' ,
type : 'integer'
} ,
reg : {
type : 'string'
}
}
} )
console . log ( stringify ( {
firstName : 'Matteo' ,
lastName : 'Collina' ,
age : 32 ,
reg : / "([^"]|\")*" /
} ) )
اختياريًا، يمكنك توفير fast-json-stringify
لكائن خيار كمعلمة ثانية:
const fastJson = require ( 'fast-json-stringify' )
const stringify = fastJson ( mySchema , {
schema : { ... } ,
ajv : { ... } ,
rounding : 'ceil'
} )
schema
: مراجع المخططات الخارجية بواسطة خاصية $ref. مزيد من التفاصيلajv
: إعدادات مثيل ajv v8 لتلك الخصائص التي تتطلب ajv
. مزيد من التفاصيلrounding
: إعداد كيفية تقريب أنواع integer
عندما لا تكون أعدادًا صحيحة. مزيد من التفاصيلlargeArrayMechanism
: قم بتعيين الآلية التي يجب استخدامها للتعامل مع المصفوفات الكبيرة (افتراضيًا 20000
عنصر أو أكثر). مزيد من التفاصيل أنشئ دالة stringify()
استنادًا إلى مواصفات مسودة jsonschema 7.
الأنواع المدعومة:
'string'
'integer'
'number'
'array'
'object'
'boolean'
'null'
والمتداخلة أيضا.
مثال | مسلسل ك |
---|---|
Date | string عبر toISOString() |
RegExp | string |
BigInt | integer عبر toString |
يتم دعم التنسيقات المضمنة في مخطط JSON للتواريخ وسيتم تسلسلها على النحو التالي:
شكل | مثال على تنسيق متسلسل |
---|---|
date-time | 2020-04-03T09:11:08.615Z |
date | 2020-04-03 |
time | 09:11:08 |
ملاحظة : في حالة تنسيق التاريخ وليس كائن التاريخ، لن يكون هناك أي تلاعب به. وينبغي أن يتم تنسيقه بشكل صحيح.
مثال مع كائن التاريخ:
const stringify = fastJson ( {
title : 'Example Schema with string date-time field' ,
type : 'string' ,
format : 'date-time'
} )
const date = new Date ( )
console . log ( stringify ( date ) ) // '"YYYY-MM-DDTHH:mm:ss.sssZ"'
يمكنك تعيين حقول محددة لكائن ما كما هو مطلوب في مخططك عن طريق إضافة اسم الحقل داخل المصفوفة required
في مخططك. مثال:
const schema = {
title : 'Example Schema with required field' ,
type : 'object' ,
properties : {
nickname : {
type : 'string'
} ,
mail : {
type : 'string'
}
} ,
required : [ 'mail' ]
}
إذا كان الكائن المطلوب تسلسله يفتقد الحقل (الحقول) المطلوبة، فسوف يؤدي fast-json-stringify
إلى حدوث خطأ.
إذا كان هناك حقل موجود في المخطط (وهو غير مطلوب) ولكنه غير موجود في الكائن المطلوب تقييده، فلن يكتبه fast-json-stringify
في السلسلة النهائية. مثال:
const stringify = fastJson ( {
title : 'Example Schema' ,
type : 'object' ,
properties : {
nickname : {
type : 'string'
} ,
mail : {
type : 'string'
}
}
} )
const obj = {
mail : '[email protected]'
}
console . log ( stringify ( obj ) ) // '{"mail":"[email protected]"}'
يدعم fast-json-stringify
مفتاح jsonschema default
لإجراء تسلسل لقيمة إذا كانت undefined
أو غير موجودة.
مثال:
const stringify = fastJson ( {
title : 'Example Schema' ,
type : 'object' ,
properties : {
nickname : {
type : 'string' ,
default : 'the default string'
}
}
} )
console . log ( stringify ( { } ) ) // '{"nickname":"the default string"}'
console . log ( stringify ( { nickname : 'my-nickname' } ) ) // '{"nickname":"my-nickname"}'
يدعم fast-json-stringify
خصائص النمط كما هو محدد في مخطط JSON. يجب أن تكون خصائص النمط كائنًا، حيث يكون المفتاح عبارة عن تعبير عادي صالح وتكون القيمة كائنًا، ويتم تعريفها بهذه الطريقة: { type: 'type' }
. ستعمل PatternProperties فقط مع الخصائص التي لم يتم إدراجها بشكل صريح في كائن الخصائص. مثال:
const stringify = fastJson ( {
title : 'Example Schema' ,
type : 'object' ,
properties : {
nickname : {
type : 'string'
}
} ,
patternProperties : {
'num' : {
type : 'number'
} ,
'.*foo$' : {
type : 'string'
}
}
} )
const obj = {
nickname : 'nick' ,
matchfoo : 42 ,
otherfoo : 'str' ,
matchnum : 3
}
console . log ( stringify ( obj ) ) // '{"matchfoo":"42","otherfoo":"str","matchnum":3,"nickname":"nick"}'
يدعم fast-json-stringify
خصائص إضافية كما هو محدد في مخطط JSON. يجب أن تكون الخصائص الإضافية كائنًا أو قيمة منطقية، ويتم تعريفها بهذه الطريقة: { type: 'type' }
. ستعمل خصائص إضافية فقط مع الخصائص التي لم يتم إدراجها بشكل صريح في الخصائص وكائنات PatternProperties .
إذا لم تكن الخصائص الإضافية موجودة أو تم ضبطها على false
، فسيتم تجاهل كل خاصية غير مدرجة بشكل صريح في الخصائص وكائنات PatternProperties ، كما هو موضح في الحقول المفقودة. يتم تجاهل الحقول المفقودة لتجنب الاضطرار إلى إعادة كتابة الكائنات قبل إجراء التسلسل. ومع ذلك، قد تؤدي قواعد المخطط الأخرى إلى حدوث مواقف مماثلة. إذا تم تعيين extraProperties على true
، فسيتم استخدامه بواسطة JSON.stringify
لتقييد الخصائص الإضافية. إذا كنت ترغب في تحقيق أقصى قدر من الأداء، فإننا نشجعك بشدة على استخدام مخطط ثابت حيثما أمكن ذلك. سيتم دائمًا إجراء تسلسل للخصائص الإضافية في نهاية الكائن. مثال:
const stringify = fastJson ( {
title : 'Example Schema' ,
type : 'object' ,
properties : {
nickname : {
type : 'string'
}
} ,
patternProperties : {
'num' : {
type : 'number'
} ,
'.*foo$' : {
type : 'string'
}
} ,
additionalProperties : {
type : 'string'
}
} )
const obj = {
nickname : 'nick' ,
matchfoo : 42 ,
otherfoo : 'str' ,
matchnum : 3 ,
nomatchstr : 'valar morghulis' ,
nomatchint : 313
}
console . log ( stringify ( obj ) ) // '{"nickname":"nick","matchfoo":"42","otherfoo":"str","matchnum":3,"nomatchstr":"valar morghulis",nomatchint:"313"}'
يدعم fast-json-stringify
الكلمات الرئيسية AnyOf وواحدة من الكلمات الرئيسية كما هو محدد في مخطط JSON. يجب أن يكون كلاهما مصفوفة من مخططات JSON الصالحة. سيتم اختبار المخططات المختلفة بالترتيب المحدد. كلما زاد عدد المخططات التي يتعين على stringify
تجربتها قبل العثور على تطابق، كلما كان ذلك أبطأ.
يستخدم AnyOf و oneOf ajv كمدقق مخطط JSON للعثور على المخطط الذي يطابق البيانات. وهذا له تأثير على الأداء، استخدمه فقط كملاذ أخير.
مثال:
const stringify = fastJson ( {
title : 'Example Schema' ,
type : 'object' ,
properties : {
'undecidedType' : {
'anyOf' : [ {
type : 'string'
} , {
type : 'boolean'
} ]
}
}
} )
عند تحديد مخططات كائن JSON لـ AnyOf ، قم بإضافة الكلمة الأساسية المطلوبة للتحقق من الصحة لمطابقة الكائنات ذات الخصائص التي تريدها فقط.
مثال:
const stringify = fastJson ( {
title : 'Example Schema' ,
type : 'array' ,
items : {
anyOf : [
{
type : 'object' ,
properties : {
savedId : { type : 'string' }
} ,
// without "required" validation any object will match
required : [ 'savedId' ]
} ,
{
type : 'object' ,
properties : {
error : { type : 'string' }
} ,
required : [ 'error' ]
}
]
}
} )
يدعم fast-json-stringify
ميزة if/then/else
jsonschema. انظر وثائق عج.
مثال:
const stringify = fastJson ( {
'type' : 'object' ,
'properties' : {
} ,
'if' : {
'properties' : {
'kind' : { 'type' : 'string' , 'enum' : [ 'foobar' ] }
}
} ,
'then' : {
'properties' : {
'kind' : { 'type' : 'string' , 'enum' : [ 'foobar' ] } ,
'foo' : { 'type' : 'string' } ,
'bar' : { 'type' : 'number' }
}
} ,
'else' : {
'properties' : {
'kind' : { 'type' : 'string' , 'enum' : [ 'greeting' ] } ,
'hi' : { 'type' : 'string' } ,
'hello' : { 'type' : 'number' }
}
}
} )
console . log ( stringify ( {
kind : 'greeting' ,
foo : 'FOO' ,
bar : 42 ,
hi : 'HI' ,
hello : 45
} ) ) // {"kind":"greeting","hi":"HI","hello":45}
console . log ( stringify ( {
kind : 'foobar' ,
foo : 'FOO' ,
bar : 42 ,
hi : 'HI' ,
hello : 45
} ) ) // {"kind":"foobar","foo":"FOO","bar":42}
ملحوظة: لا تعلن عن الخصائص مرتين وإلا ستطبعها مرتين!
إذا كنت تريد إعادة استخدام تعريف القيمة، فيمكنك استخدام الخاصية $ref
. يجب أن تكون قيمة $ref
عبارة عن سلسلة بتنسيق JSON Pointer. مثال:
const schema = {
title : 'Example Schema' ,
definitions : {
num : {
type : 'object' ,
properties : {
int : {
type : 'integer'
}
}
} ,
str : {
type : 'string'
}
} ,
type : 'object' ,
properties : {
nickname : {
$ref : '#/definitions/str'
}
} ,
patternProperties : {
'num' : {
$ref : '#/definitions/num'
}
} ,
additionalProperties : {
$ref : '#/definitions/def'
}
}
const stringify = fastJson ( schema )
إذا كنت بحاجة إلى استخدام تعريف خارجي، فيمكنك تمريره كخيار لـ fast-json-stringify
. مثال:
const schema = {
title : 'Example Schema' ,
type : 'object' ,
properties : {
nickname : {
$ref : 'strings#/definitions/str'
}
} ,
patternProperties : {
'num' : {
$ref : 'numbers#/definitions/num'
}
} ,
additionalProperties : {
$ref : 'strings#/definitions/def'
}
}
const externalSchema = {
numbers : {
definitions : {
num : {
type : 'object' ,
properties : {
int : {
type : 'integer'
}
}
}
}
} ,
strings : require ( './string-def.json' )
}
const stringify = fastJson ( schema , { schema : externalSchema } )
يمكن أن تشير التعريفات الخارجية أيضًا إلى بعضها البعض. مثال:
const schema = {
title : 'Example Schema' ,
type : 'object' ,
properties : {
foo : {
$ref : 'strings#/definitions/foo'
}
}
}
const externalSchema = {
strings : {
definitions : {
foo : {
$ref : 'things#/definitions/foo'
}
}
} ,
things : {
definitions : {
foo : {
type : 'string'
}
}
}
}
const stringify = fastJson ( schema , { schema : externalSchema } )
افتراضيًا، ستتعامل المكتبة تلقائيًا مع BigInt.
سيتم اقتطاع خاصية type: integer
إذا تم توفير نقطة عائمة. يمكنك تخصيص هذا السلوك باستخدام خيار rounding
الذي يقبل round
أو ceil
أو floor
أو trunc
. الافتراضي هو trunc
:
const stringify = fastJson ( schema , { rounding : 'ceil' } )
وفقًا لمواصفات Open API 3.0، يجب الإعلان عن القيمة التي يمكن أن تكون nullable
.
const stringify = fastJson ( {
'title' : 'Nullable schema' ,
'type' : 'object' ,
'nullable' : true ,
'properties' : {
'product' : {
'nullable' : true ,
'type' : 'object' ,
'properties' : {
'name' : {
'type' : 'string'
}
}
}
}
} )
console . log ( stringify ( { product : { name : "hello" } } ) ) // "{"product":{"name":"hello"}}"
console . log ( stringify ( { product : null } ) ) // "{"product":null}"
console . log ( stringify ( null ) ) // null
بخلاف ذلك، بدلاً من ظهور خطأ، سيتم فرض القيم الخالية على النحو التالي:
integer
-> 0
number
-> 0
string
-> ""
boolean
-> false
object
-> {}
array
-> []
يتم تعريف المصفوفات الكبيرة، في نطاق هذا المستند، على أنها صفائف تحتوي افتراضيًا على 20000
عنصر أو أكثر. يمكن تعديل هذه القيمة عبر معلمة الخيار largeArraySize
.
في مرحلة ما، يبدأ الحمل الناتج عن الآلية الافتراضية التي تستخدمها fast-json-stringify
للتعامل مع المصفوفات في الزيادة بشكل كبير، مما يؤدي إلى بطء عمليات التنفيذ بشكل عام.
من أجل تحسين ذلك، يمكن للمستخدم تعيين خيارات largeArrayMechanism
و largeArraySize
.
القيمة الافتراضية لـ largeArrayMechanism
هي default
. القيم الصالحة لذلك هي:
default
- يعد هذا الخيار بمثابة حل وسط بين الأداء ومجموعة الميزات من خلال الاستمرار في توفير الوظائف المتوقعة من هذا lib ولكن مع التخلي عن بعض مكاسب الأداء المحتملة. باستخدام مجموعة الخيارات هذه، سيتم ربط المصفوفات الكبيرة عن طريق ربط عناصرها المصفوفة باستخدام Array.join
بدلاً من تسلسل السلسلة للحصول على أداء أفضلjson-stringify
- سيؤدي هذا الخيار إلى إزالة دعم التحقق من صحة المخطط داخل المصفوفات الكبيرة تمامًا. ومن خلال القيام بذلك، يتم إلغاء النفقات العامة المذكورة سابقًا، مما يؤدي إلى تحسين وقت التنفيذ بشكل كبير. ضع في اعتبارك أنه لا يوجد تغيير في سلوك المصفوفات التي لا تعتبر كبيرة القيمة الافتراضية لـ largeArraySize
هي 20000
. القيم الصالحة له هي قيم تشبه الأعداد الصحيحة، مثل:
20000
2e4
'20000'
'2e4'
- لاحظ أنه سيتم تحويل هذا إلى 2
، وليس 20000
1.5
- لاحظ أنه سيتم تحويل هذا إلى 1
بشكل افتراضي، تفلت المكتبة من كافة السلاسل. باستخدام التنسيق "غير الآمن"، لا يتم هروب السلسلة. وهذا ينطوي على مشكلة أمنية خطيرة محتملة. لا يمكنك استخدامه إلا إذا كنت متأكدًا من أن بياناتك لا تحتاج إلى الهروب. الميزة هي تحسن كبير في الأداء.
مثال:
const stringify = fastJson ( {
title : 'Example Schema' ,
type : 'object' ,
properties : {
'code' : {
type : 'string' ,
format 'unsafe'
}
}
} )
كمرجع، إليك بعض المعايير للمقارنة بين الآليات الثلاث. المعايير التي أجريت على الجهاز القديم.
ST1000LM024 HN-M 1TB HDD, Intel Core i7-3610QM @ 2.3GHz, 12GB RAM, 4C/8T
.v16.13.1
JSON.stringify large array x 157 ops/sec ±0.73% (86 runs sampled)
fast-json-stringify large array default x 48.72 ops/sec ±4.92% (48 runs sampled)
fast-json-stringify large array json-stringify x 157 ops/sec ±0.76% (86 runs sampled)
compile-json-stringify large array x 175 ops/sec ±4.47% (79 runs sampled)
AJV Serialize large array x 58.76 ops/sec ±4.59% (60 runs sampled)
تعامل مع تعريف المخطط كرمز تطبيق، فليس من الآمن استخدام المخططات المقدمة من قبل المستخدم.
لتحقيق تنقيح منخفض التكلفة وأداء عالٍ، يقوم fast-json-stringify
بإنشاء وظيفة وتجميعها (باستخدام مُنشئ Function
) عند التهيئة. على الرغم من أن schema
يتم التحقق من صحته حاليًا بحثًا عن أي أخطاء للمطورين، إلا أنه ليس هناك ما يضمن أن توفير المخطط الذي أنشأه المستخدم لن يؤدي إلى تعريض تطبيقك للهجمات عن بُعد.
يتحمل المستخدمون مسؤولية إرسال البيانات الموثوقة. يضمن fast-json-stringify
أنك لن تحصل على مخرجات صالحة إلا إذا كانت مدخلاتك مطابقة للمخطط أو يمكن إجبارها على المخطط. إذا لم تتطابق مدخلاتك مع المخطط، فسوف تحصل على سلوك غير محدد.
يمكن تنشيط وضع التصحيح أثناء التطوير لفهم ما يحدث عندما لا تعمل الأمور كما تتوقع.
const debugCompiled = fastJson ( {
title : 'default string' ,
type : 'object' ,
properties : {
firstName : {
type : 'string'
}
}
} , { mode : 'debug' } )
console . log ( debugCompiled ) // it is a object contain code, ajv instance
const rawString = debugCompiled . code // it is the generated code
console . log ( rawString )
const stringify = fastJson . restore ( debugCompiled ) // use the generated string to get back the `stringify` function
console . log ( stringify ( { firstName : 'Foo' , surname : 'bar' } ) ) // '{"firstName":"Foo"}'
يتم استخدام الوضع المستقل لتجميع التعليمات البرمجية التي يمكن تشغيلها مباشرة بواسطة node
نفسها. يجب أن يكون لديك fast-json-stringify
مثبتًا حتى يعمل الكود المستقل.
const fs = require ( 'fs' )
const code = fastJson ( {
title : 'default string' ,
type : 'object' ,
properties : {
firstName : {
type : 'string'
}
}
} , { mode : 'standalone' } )
fs . writeFileSync ( 'stringify.js' , code )
const stringify = require ( 'stringify.js' )
console . log ( stringify ( { firstName : 'Foo' , surname : 'bar' } ) ) // '{"firstName":"Foo"}'
تم رعاية هذا المشروع من قبل nearForm.
معهد ماساتشوستس للتكنولوجيا