Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the deal with optimising arguments?

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:

Why?

  • What technical challenges prevent the optimisation from taking place?
  • Why can't the v8 engine simply return a standard array of arguments, just like the second code sample shows and optimise the function?
  • For extra points, why is the 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?
like image 297
Robert Rossmann Avatar asked Mar 22 '15 18:03

Robert Rossmann


People also ask

Why is optimization important?

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.

What does it mean to optimize parameters?

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.

How optimization works?

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.

What does it mean to optimize a function?

Mathematically speaking, optimization is the minimization or maximization of a function subject to constraints on its variables.


3 Answers

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.

like image 50
Vyacheslav Egorov Avatar answered Oct 25 '22 17:10

Vyacheslav Egorov


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.

like image 25
Esailija Avatar answered Oct 25 '22 17:10

Esailija


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.

like image 43
beautifulcoder Avatar answered Oct 25 '22 18:10

beautifulcoder