⬆️ ⬇️

Subtleties Javascript / Node.js. Increase productivity tenfold

Introduction



There is a need to exchange messages between the server and the client in binary form, but in the JSON format in the end. I started to google, what are the libraries packing in a binary form. Revised a lot: MesssagePack, Bson, protobuf, capnproto.org and others. But all these libraries allow you to pack and unpack ready binary packages. Not really dug, is it possible to do a parser of incoming traffic in chunks. But that's not the point. I never encountered such a task and decided to play around with the node and make my own. Where do without crutches and bicycles? And what are the features of Node.js I encountered ...



I wrote a packer and launched ...



var start = Date.now(); for (i=0; i < 1000000; i++) { packer.pack({abc: 123, cde: 5}); } console.log(Date.now() - start); 


Issued ~ 4300 . Surprised ... Why so long? While the code is:



 var start = Date.now(); for (i=0; i < 1000000; i++) { JSON.stringify({abc: 123, cde: 5}); } console.log(Date.now() - start); 


Issued ~ 350 . Not understood. I started digging my code and looking for where a lot of resources are used. And found.

')

Run this code:



 function find(val){ function index (value) { return [1,2,3].indexOf(value); } return index(val); } var start = Date.now(); for (i=0; i < 1000000; i++) { find(2); } console.log(Date.now() - start); 


Issues 1908 . You say: yes, this is not a lot of 1,000,000 repetitions. And if I say that much? Run this code:



 function index (value) { return [1,2,3].indexOf(value); } function find(val){ return index(val); } var start = Date.now(); for (i=0; i < 1000000; i++) { find(2); } console.log(Date.now() - start); 


Gives out 16 . My colleagues were outraged too, but also noticed that the function is created dynamically and is immediately destroyed, you carried it out and there is no such load . From the experiment conclusion: dynamic functions are not cached in binary form. I agreed and objected: yes, but there are no variables in SCOPE that are used inside it. It seems that the Google engine always copies SCOPE.



OK. I optimized this functionality and launched it ... and still. Issued ~ 3000. Again surprised. And once again I’ve gotten to dig ... and found another joke.



Run this code:



 function test (object) { var a = 1, b = [], c = 0 return { abc: function (val) { } } } var start = Date.now(); for (i=0; i < 1000000; i++) { var a = test(); a.abc(); } console.log(Date.now() - start); 


Issued 34. Now, let's say we need to create an Array inside abc :



 function test (object) { var a = 1, b = [], c = 0 return { abc: function () { var arr1 = []; } } } var start = Date.now(); for (i=0; i < 1000000; i++) { var a = test(); a.abc(); } console.log(Date.now() - start); 


Issued 1826 . It was getting dark ... And if we need 3 arrays?



 function test (object) { var a = 1, b = [], c = 0 return { abc: function () { var arr1 = [], arr2 = [], arr3 = []; } } } var start = Date.now(); for (i=0; i < 1000000; i++) { var a = test(); a.abc(); } console.log(Date.now() - start); 


Issued 5302! Here it is jokes. It seemed that we were not using SCOPE, and the creation of an empty array should take a whole penny. It was not there.



I think ... And I will replace the objects. The result is better, but not by much. Issued 1071 .



Now focus. Many will say: you again endure the function. Yes. But the focus is different.



 function abc () { var arr1 = [], arr2 = [], arr3 = []; } function test (object) { var a = 1, b = [], c = 0 return { abc: abc } } var start = Date.now(); for (i=0; i < 1000000; i++) { var a = test(); a.abc(); } console.log(Date.now() - start); 


Many will notice and say: there will be the same time. And it was not there. Issued 25 . Although arrays were created as many times. We conclude: creating arrays in a dynamic function spends a lot of resources . Question: why?



Now back to the first problem. But in other way. We take out the Array :



 var indexes = [1,2,3]; function find(val){ function index (value) { return indexes.indexOf(value); } return index(val); } var start = Date.now(); for (i=0; i < 1000000; i++) { find(2); } console.log(Date.now() - start); 


And I was right. Issued 58. With the removal of the entire function, issued 16 . Those. creating a function is not a particularly resource-intensive process. We also refute the previous conclusion:

The binary code of functions is still cached in memory. And creating objects in a dynamic function takes a lot of time.



I used to assume differently: all static / expression objects created temporarily are immediately compiled as function code. And it turns out, no. We conclude:

The Google engine at each launch creates new objects and fills it with the necessary values, and then it evaluates the expression, which is not good.



And what subtleties did you encounter? Comments are welcome.

Source: https://habr.com/ru/post/277823/



All Articles