It is a known fact that using arguments
improperly in JavaScript may result in a function not being optimisable (see here and here by the end):
function notOptimisable (a, b) {
// Optimising compiler says: Nope.
var args = [].slice.call(arguments)
}
However, none of the sources have so far managed to explain why this prevents the optimisation from happening.
It is even more mind-boggling as all I have to do is
function optimisable (a, b) {
// Optimising compiler says: I can do this!
var args = new Array(arguments.length)
, i = 0
// Copy the arguments into an actual array, very carefully...
for(i; i < args.length; ++i)
args[i] = arguments[i]
}
and voilá - I have a copy of arguments
that is an actual array and the function can be optimised:
node --trace_opt --trace_deopt script.js # Exerpt below
[marking 0x24ba2c0bf0f1 <JS Function notoptimisable (SharedFunctionInfo 0x26b62a724859)> for recompilation, reason: small function, ICs with typeinfo: 3/3 (100%), generic ICs: 0/3 (0%)]
[disabled optimization for 0x26b62a724859 <SharedFunctionInfo notoptimisable>, reason: Bad value context for arguments value]
[failed to optimize notoptimisable: Bad value context for arguments value]
[marking 0x24ba2d0041b1 <JS Function optimisable (SharedFunctionInfo 0x26b62a7247b1)> for recompilation, reason: small function, ICs with typeinfo: 7/7 (100%), generic ICs: 0/7 (0%)]
[optimizing 0x24ba2d0041b1 <JS Function optimisable (SharedFunctionInfo 0x26b62a7247b1)> - took 0.039, 0.164, 0.051 ms]
Thus, I ask thee:
arguments
only an "array-like" object from the language design perspective (i.e. it has numeric keys, but it is not a descendant of Array) and does that somehow play a role in the optimisation process?The purpose of optimization is to achieve the “best” design relative to a set of prioritized criteria or constraints. These include maximizing factors such as productivity, strength, reliability, longevity, efficiency, and utilization.
A fancy name for training: the selection of parameter values, which are optimal in some desired sense (eg. minimize an objective function you choose over a dataset you choose). The parameters are the weights and biases of the network.
Optimization means finding the optimal value or number or in other words, the best possible option. With work optimization, the utilization of the resources in use can be planned to be as effective and cost-efficient as possible.
Mathematically speaking, optimization is the minimization or maximization of a function subject to constraints on its variables.
There are no insurmountable technical challenges. It was just a shortcut decision made during implementation of arguments object in Crankshaft: to support only cases where arguments object materialization can be easily avoided.
Even if Crankshaft supported materialization of arguments object the resulting code would still be slower than code that does not allocate arguments object.
It's just a question of supporting the fastest case in 10 minutes vs. supporting slower, but more generic case, in 10 days. (10 minutes / 10 days are imaginary numbers, I am just trying to convey the difference in scale of the implementation complexity).
If one wants to support the case when arguments object is materialize (and potentially leaks) then one needs to account for aliasing between arguments object and parameters - which changes how SSA form is constructed for these variables. This also complicates inlining for similar reasons.
A more generic approach to arguments object should have been based on the escape analysis / allocation sinking pass - but Crankshaft did not have anything like that when it was implemented and it still needed to support at least some fast path for arguments manipulation.
arguments
is not an array, for example, consider:
function abc(a) {
arguments[0] = 1;
console.log(a);
}
abc(0);
The problem here is that the assignment of arguments[0] = 1
changed the value of a
magically, I.E. arguments[0]
aliases a
. It's the same problem that eval
and with
causes - you can no longer statically see what variables are being changed and when.
Under strict mode
which removes the aliasing misfeature there is no technical reason why this wouldn't be optimizable, however it might have been deemed to be not worth it as most of the web doesn't use strict mode in the first place or remove it for production code.
The reason might be because JavaScript does not implement actual arrays in the traditional sense. Arrays are more like JavaScript objects, i.e. {}
, that have a length property. The fact that arguments
is not an Array
was design mistake in the language. This is likely the reason why the optimizer has problems with this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With