问题
We are trying a way to receive web components via WebSockets. Those components contains custom scripts and they should be run in a context inside the component.
In short, we have some script strings and want to run them.
Right now we are using eval
for this, something like this:
function ctxEval(ctx, __script) {
eval(__script);
// return things with the ctx
}
and works as expected, but I'm reading that any function containing eval
is not optimized by V8. I thought into converting it to new Function()
like this:
new Function("ctx", __script)(ctx);
this way I can achieve the same as the ctxEval
function above.
We know that Function
is eval()
because they act almost equally, but the question now is, until which point Function
is eval()
? Maybe because Function()
has its own scope instead of the eval
one which runs the code in the same scope, the function containing the Function
call is actually optimized by V8. Also, here they talk about eval
but not about Function
constructor.
And another question implied in this one is, is the script that runs inside Function()
optimized by V8?
回答1:
I just tested 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);
run command
$ node --allow-natives-syntax js.js
and the output 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 bailots and im realy surprised because it looks that eval
is also optimized :>
EDIT 2:
After some additional research I found this https://blog.sqreen.io/optimize-your-node-app-by-simply-upgrading-node-js/
来源:https://stackoverflow.com/questions/44332793/is-the-function-constructor-not-optimized-by-v8-like-eval