2

By this jsPerf, the construct

var fn2 = new Function('return 1 + 2;');

yields a function which takes more time to be called than the function defined by:

var fn1 = function() {
    return 1 + 2;
};

Why is this so? Apparently the overhead lies only in calling the function, not in running its body (so the body itself is apparently optimized). This has be shown by other tests on jsperf.

Using the function constructor makes sense when dynamically generating code (i.e. using SpiderMonkey as a Javascript JIT compiler) so it is bad to see that there is a performance penalty. (Using eval instead of the function constructor is faster but eval makes the whole scope accessible to the function which is not what I want.)

It is interesting to see that this version

var fn4 = new Function('return function () { return 1 + 2; }')();

returns a function as fast as fn1 from above. However, doesn't this blow-up the inner function as it still carries around a handle to the empty scope of the outer function? (Assume that I have to create many of these functions so that these micro-optimizations could make sense.)

Just a student
  • 10,560
  • 2
  • 41
  • 69
Marc
  • 4,327
  • 4
  • 30
  • 46
  • Since your function does not use any variables, scopes are probably irrelevant. – Bergi Jan 09 '14 at 17:39
  • 1
    Maybe check [this question](http://stackoverflow.com/q/20695573/1048572) to understand the cited statement from MDN. Still, I'm curious how those functions you created are different in jit-optimisation. – Bergi Jan 09 '14 at 17:48
  • 2
    If you just call both normally, they both seem to be optimized equally well. In fact, in all the tests I've written outside of jsperf I haven't been able to find a difference in how fn1 and fn2 are called.... I wonder what jsperf is doing weirdly here to get them to behave differently. – Boris Zbarsky Jan 10 '14 at 07:10

1 Answers1

2

Looks like there was a bug in the SpiderMonkey JIT where it sometimes failed to properly inline functions created with new Function. Note that in this testcase once all the functions are inlined all that's really being timed is the empty loop, since the function bodies are constant and get loop-hoisted...

In any case, https://bugzilla.mozilla.org/show_bug.cgi?id=958797 tracks the fix for the inlining issue.

Boris Zbarsky
  • 34,758
  • 5
  • 52
  • 55