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

自闭症网瘾萝莉.ら 提交于 2019-12-10 14:53:24

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!