Is the Function () constructor not optimized by V8 like eval?

We are trying to get web components through WebSockets. These components contain user scripts and should be run in context within the component.

In short, we have several script lines and want to run them.

Now we use eval to do this, something like this:

 function ctxEval(ctx, __script) { eval(__script); // return things with the ctx } 

and it works as expected, but I read that any function containing eval is not optimized by V8. I decided to convert it to new Function() as follows:

 new Function("ctx", __script)(ctx); 

this way I can achieve the same as ctxEval above.

We know that Function is eval() , because they act almost the same, but now the question is, to what point is Function eval() ? Perhaps because Function() has its own scope instead of eval , which runs code in the same scope, the function containing the Function call is actually optimized by V8. Also, here they talk about eval , but not the Function constructor.

And another question implied in this is a script that works inside Function() optimized with V8?

+3
source share
1 answer

I just checked this with this code

 const adder = new Function('a', 'b', 'return b%2 ? a + b : b%3 ? a - b : b%5 ? b / a : a * b'); let b = 0, b2 = 0; function _throw() { throw new Error('Ups'); } function _catch() { try {_throw()} catch(e) {} } function printStatus(fn) { switch (%GetOptimizationStatus(fn)) { case 1: console.log(fn.name, "function is optimized"); break; case 2: console.log(fn.name, "function is not optimized"); break; case 3: console.log(fn.name, "function is always optimized"); break; case 4: console.log(fn.name, "function is never optimized"); break; case 6: console.log(fn.name, "function is maybe deoptimized"); break; } } eval('function evil(a,b) {return b%2 ? a + b : b%3 ? a - b : b%5 ? b / a : a * b}'); printStatus(adder); printStatus(evil); printStatus(_throw); printStatus(_catch); // Call the function for(let i = 0; i < 2000; i++) { b = adder(Math.random() * 10, b); b2 = evil(i, b2); _catch(); } printStatus(adder); printStatus(evil); printStatus(_throw); printStatus(_catch); 

execute command

 $ node --allow-natives-syntax js.js 

and the way out is

 anonymous function is not optimized evil function is not optimized _throw function is not optimized _catch function is not optimized anonymous function is optimized evil function is optimized _throw function is not optimized _catch function is not optimized 

EDIT:

I modified this test code to check other gateways, and I'm really surprised because it looks like eval also optimized:>

EDIT 2:

After some additional research, I found this https://blog.sqreen.io/optimize-your-node-app-by-simply-upgrading-node-js/

+2
source

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


All Articles