TypedJSON
TypedJSON copied to clipboard
Performance?
Nice work! Any measurement of using TypedJSON vs plain JSON (not typed) or other methods of deserialization?
Thank you, @gerleim
I'm afraid no such thing has been done up until now, as we never experienced performance issues in AudioNodes regarding TypedJSON (and we are serializing/deserializing "rather large" structures).
That said, it should be easy to measure performance for one particular case. What TypedJSON does is nothing more than a simple set of 2-way conversions between these 3 steps:
json <-> untyped object tree <-> typed object tree
JSON.stringify and JSON.parse are used internally with the untyped object tree, so everything else is TypedJSON doing the conversions.
With that in mind, given an object tree o with every single property annotated properly (so that no properties are skipped), the execution time difference between calling JSON.stringify(o) and TypedJSON.stringify(o) should accurately represent the overhead added by TypedJSON.
Similarly for de-serialization, given a JSON string s, the difference between JSON.parse(s) and TypedJSON.parse(s) should accurately represent the overhead added by TypedJSON, given the JSON is an exact representation of an object tree (i.e. no extra objects in JSON).
@JohnWeisz @gerleim
I've ran a test.
Program 1 : Without TypedJSON
//tslint:disable
const microtime = require('microtime')
const startTime = microtime.now();
const json = '{ "first_name": "John", "last_name": "Doe"}';
class User {
constructor(
public first_name: string,
public last_name: string
) {
}
public getFullName = (): string => {
return this.first_name + ' ' + this.last_name;
};
public static fromJSON = (json: string): User => {
const jsonObject = JSON.parse(json);
return new User(
jsonObject.first_name,
jsonObject.last_name
);
};
}
const user: User = User.fromJSON(json);
console.log(user.first_name); // Works, prints "John"
console.log(user.last_name); // Works, prints "Doe"
console.log(user.getFullName()); //Error: TypeError: user.getFullName is not a function
const endTime = microtime.now();
console.log(`Took ${endTime - startTime} microseconds`);
Program 2: With TypedJSON
//tslint:disable
const microtime = require('microtime')
const startTime = microtime.now();
import { JsonMember, JsonObject, TypedJSON } from 'typedjson-npm';
const json = '{ "first_name": "John", "last_name": "Doe"}';
@JsonObject
class User {
@JsonMember({ type: String })
first_name: string;
@JsonMember({ type: String })
last_name: string;
public getFullName = (): string => {
return this.first_name + ' ' + this.last_name;
};
}
const user: User = TypedJSON.parse(json, User);
console.log(user.first_name);
console.log(user.last_name);
console.log(user.getFullName());
const endTime = microtime.now();
console.log(`Took ${endTime - startTime} microseconds`);
Output : Program 1 : Without TypedJSON
John
Doe
John Doe
Took 1471 microseconds
Output : Program 2 : With TypedJSON
John
Doe
John Doe
Took 5364 microseconds
I am not pro in benchmarking stuff. This is my first time I am comparing performance. Can this test considered as a valid one ?
Test with nested object
Without TypedJSON
//tslint:disable
const microtime = require('microtime')
const startTime = microtime.now();
const json = '{ "first_name": "John", "last_name": "Doe","car":{"name":"BMW","series":"2018"}}';
class Car {
constructor(
public name : string,
public series : string
){}
public getNameWithSeries(){
return this.name+' '+this.series
}
}
class User {
constructor(
public first_name: string,
public last_name: string,
public car : Car
) {
}
public getFullName = (): string => {
return this.first_name + ' ' + this.last_name;
};
public static fromJSON = (json: string): User => {
const jsonObject = JSON.parse(json);
return new User(
jsonObject.first_name,
jsonObject.last_name,
new Car(
jsonObject.car.name,
jsonObject.car.series,
)
);
};
}
const user: User = User.fromJSON(json);
console.log(`First name : ${user.first_name}`);
console.log(`Last name : ${user.last_name}`);
console.log(`Full name : ${user.getFullName()}`);
console.log(`Car with series : ${user.car.getNameWithSeries()}`);
const endTime = microtime.now();
console.log(`Took ${endTime - startTime} microseconds`);
With TypedJSON
//tslint:disable const microtime = require('microtime') const startTime = microtime.now();
import { JsonMember, JsonObject, TypedJSON } from 'typedjson-npm';
const json = '{ "first_name": "John", "last_name": "Doe","car":{"name":"BMW","series":"2018"}}';
@JsonObject
class Car{
@JsonMember({type : String})
name : string
@JsonMember({type : String})
series : string
public getNameWithSeries = () =>{
return this.name + ' '+ this.series;
}
}
@JsonObject
class User {
@JsonMember({type : String})
first_name: string;
@JsonMember({type : String})
last_name: string;
@JsonMember({type : Car})
car : Car
public getFullName = (): string => {
return this.first_name + ' ' + this.last_name;
};
}
const user: User = TypedJSON.parse(json, User);
console.log(`First name : ${user.first_name}`);
console.log(`Last name : ${user.last_name}`);
console.log(`Full name : ${user.getFullName()}`);
console.log(`Car with series : ${user.car.getNameWithSeries()}`);
const endTime = microtime.now();
console.log(`Took ${endTime - startTime} microseconds`);
Output : With TypedJSON
First name : John
Last name : Doe
Full name : John Doe
Car with series : BMW 2018
Took 5604 microseconds
Output : Without TypedJSON
First name : John
Last name : Doe
Full name : John Doe
Car with series : BMW 2018
Took 1684 microseconds