Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

performance issues with attrFunction/attrFunctionNS in attr.js #110

Closed
mutsys opened this issue Jan 20, 2017 · 6 comments
Closed

performance issues with attrFunction/attrFunctionNS in attr.js #110

mutsys opened this issue Jan 20, 2017 · 6 comments

Comments

@mutsys
Copy link

mutsys commented Jan 20, 2017

I came across this while profiling one of my apps:

screen shot 2017-01-19 at 4 04 12 pm

It seems that the function at issue here:

function attrFunction(name, value) {
  return function() {
    var v = value.apply(this, arguments);
    if (v == null) this.removeAttribute(name);
    else this.setAttribute(name, v);
  };
}

and its sibling, attrFunctionNS, are written in such a manner that the optimized code gets discarded by the v8 compiler and it falls back to the unoptimized code instead. The details can be found here:

GoogleChrome/devtools-docs#53

listed as item 4 in the section What is a deopt?

Looking at the implementation of the function, it seems that it specifically is fouling the compiler as described in this comment in the thread:

GoogleChrome/devtools-docs#53 (comment)

and the fix would seem to be to modify the function as follows:

function attrFunction(name, value) {
  return function() {
    var args = new Array(arguments.length);
    for (var i = 0, l = arguments.length; i < l; i++) {
      args[i] = arguments[i];
    }
    var v = value.apply(this, args);
    if (v == null) this.removeAttribute(name);
    else this.setAttribute(name, v);
  };
}
@mutsys
Copy link
Author

mutsys commented Jan 20, 2017

Quick follow up: I performed this modification locally in my project and it does seem to resolve the issue. Chrome/v8 no longer deoptimizes the function.

screen shot 2017-01-19 at 5 30 42 pm

Additionally, this issue is not limited to just this function. Many similarly written functions exist all through d3-selection. It would appear that there is an opportunity to improve performance across a significant cross-section of d3-selection without a lot of effort.

@mbostock
Copy link
Member

Ugh.

According to GoogleChrome/devtools-docs#53 (comment) and https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#what-is-safe-arguments-usage, “STRICTLY fn.apply(y, arguments) is ok”. Is there something else going on here?

@mbostock
Copy link
Member

Also, 0.97ms self time still isn’t a significant amount of time (though I’m not sure how long you were profiling for), so it might not be worth fixing even if there is a deopt warning.

@mutsys
Copy link
Author

mutsys commented Jan 20, 2017

@mbostock I will provide most specific details on the overall impact of the change in my application. In the meanwhile, take a look at the difference between the timings before and after in above screenshots. They illustrate the difference (0.97ms/3.53ms -> 0.58ms/1.15ms) for **a single invocation **. One invocation out of 10s of 1000s that occured within the profiling session. This shakes out to an improvement of a couple of percentage points overall and appears to be significant in my application.

I recognize that not all applications might see this sort of improvement. My app happens to benefit from it greatly becuase I am constantly updating a number of graphs that are updated live and continuously from data streaming from multiple RESTful data sources simultaneously and it is meant to run continuously for an extended period of time. If you just draw a few hundred data points as a one-time operation, this is likely an optimization that you can live without.

I will provide you with a detailed breakdown of the impact later tonight.

@mbostock
Copy link
Member

If you can share numbers on aggregate performance rather than a single invocation that would be more helpful in evaluating the impact of this change. Thank you!

@mbostock
Copy link
Member

Closing to inactivity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants