Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which way of object instance creation is the fastest in TypeScript?

I have the following 3 different ways of creating an object instance.

I was wondering which of one of these is faster, takes less memory and why?

//Option 1        
export interface Animal1 {
    name: string;
    color: string;
    isHungry: boolean;
}
let animal: Animal1 = {
    name: 'cat',
    color: 'brown',
    isHungry: true
};

//Option 2   
export class Animal2 {
    name: string;
    color: string;
    isHungry: boolean;
}
let animal2: Animal2 = new Animal2();
animal2.name = 'cat';
animal2.color = 'brown';
animal2.isHungry = true;
     
//Option 3   
export class Animal3 {
    constructor(public name:string, public color:string, public isHungry:boolean) {}
}
let animal3 = new Animal3('cat', 'brown', true);

As of coding style and maintenance I prefer option 1 with builder classes in unit testing. Option 3 is the least favourite as it's:

  • Difficult to create an object easily, you have to set all properties
  • Difficult to maintain, every time a new property is added you need to update every single instance creation
  • Error prone, when the number of properties with the same type is high, e.g string, string, string. You may set the wrong property.

Is there any performance/memory difference between these three?

like image 292
shiva Avatar asked Aug 22 '18 19:08

shiva


People also ask

How do you create a object in TypeScript?

Syntax. var object_name = { key1: “value1”, //scalar value key2: “value”, key3: function() { //functions }, key4:[“content1”, “content2”] //collection }; As shown above, an object can contain scalar values, functions and structures like arrays and tuples.

Which keyword refers to a class instance in TypeScript?

TypeScript defines a constructor using the constructor keyword. A constructor is a function and hence can be parameterized. The this keyword refers to the current instance of the class.

Which one of the following options correctly instantiates an object of a class in TypeScript?

A constructor is used to initialize an object. In TypeScript, the constructor method is always defined with the name "constructor." In the constructor, we can access the member of a class by using this keyword.

Is TypeScript object-oriented?

In TypeScript, we can use common object-oriented patterns. One of the most fundamental patterns in class-based programming is being able to extend existing classes to create new ones using inheritance.


2 Answers

It is not possible to say, in a general sense, which is “fastest”.

Object instance creation is highly optimized in JavaScript engines. The speed will be affected by the surrounding code, the frequency with which it is run, the runtime version and many other factors.

I’m sorry this is not the answer you wanted.

In terms of memory, you can simply count the objects created by each approach - but unless you are writing a highly optimized piece of JavaScript (unlikely), this will be moot.

Typically your choice of pattern for object creation should be driven not by performance, but by non-functional requirements like the style of code agreed by the team, maintainability and API shape.

Of course, algorithms written in TS or JS can still be analysed for time and space complexity in the usual way.

like image 114
Ben Aston Avatar answered Nov 04 '22 17:11

Ben Aston


The same as in JavaScript. There might be the little difference in object creation times, but the noticeable impact on overall performance of the code which uses these types. These options are not equal.

The reason is "hidden classes" JIT optimization and things JIT can do with the monomorphic code. If object members are always initialized in the same order, JIT can assign the same "hidden class" to all of the type instances and then use this information to access class members using memory offset instead of the expensive hash table lookup. When you iterate through the collection of objects having the same hidden class (or repeatedly call the function with arguments having the same hidden classes) JIT can recognize the monomorphic code and compile the specialized version of the function with excessive type checks omitted, dynamically inline method calls, and do some other magic which makes modern JS VM so fast.

So, in general, the monomorphic code is faster than the polymorphic one, and the order of properties initialization is being used by JIT to determine the "internal object type".

https://draft.li/blog/2016/12/22/javascript-engines-hidden-classes/

https://richardartoul.github.io/jekyll/update/2015/04/26/hidden-classes.html

The easiest and safest way to enable these optimizations is to use the class and make sure that all class members are always initialized in the same order in its constructor which is an option 3 from your example. Option 2 is the worst as there's no guarantee that the "hidden class" will be the same for the different class instances, and JIT won't consider them having the same type.

The last but not least. There's nothing obvious about JS JIT performance. Not only JIT engines use slightly different (yet very sophisticated) optimization strategies, but they evolve at a time which makes the majority of articles about JIT internals obsolete in quite a short period of time. However, "hidden classes" or similar optimizations allowing JIT to take advantage of the monomorphic code are fundamental for the JS JIT performance.

Anyway, don't guess about performance and don't believe in seemingly obvious things others say. Measure it.

like image 3
gaperton Avatar answered Nov 04 '22 18:11

gaperton