Over a million developers have joined DZone.

A New Approach to Function.prototype.bind

DZone's Guide to

A New Approach to Function.prototype.bind

I’ve been working on a new approach to implement Bound Function Exotic Objects in V8 for a few months now. After a lot of yak shaving, I've now reached a point where I’m close to landing my new baseline implementation for Function.prototype.bind. Read on to learn more.

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

The performance and compatibility of Function.prototype.bind and the resulting bound function objects has traditionally always been an issue in V8 (and thereby in Chromium-based browsers and Node.js driven servers).

Consider the following simple test driver, which defines a (non-trivial) test functionfoo and creates two bound functions foo1 and foo2 based on it, which both bind the receiver and the first argument to some primitive.

"use strict";
function foo(x, y, z) { return this + x + y + z }
var foo1 = foo.bind(1, 0);
var foo2 = foo.bind(2, 1);
function test() {  // Performance test.
  var sum = 0;
  const limit = 1000;
  for (var y = 0; y < limit; ++y) {
    for (var z = 0; z < limit; ++z) {
      sum += foo1(y, z) + foo2(y, z);
  return sum;
for (let i = 0; i < 10; ++i) test(); // Warmup first.
var startTime = Date.now();
for (let i = 0; i < 10; ++i) test();
var endTime = Date.now();
print("Time: " + (endTime - startTime) + "ms.");

Now running this program with V8 tip-of-tree as of today requires a whopping 12,078ms to execute the test loop on a HP z620 work station running Ubuntu 14.04. Looking at the performance profile, almost all the time is spent in theboundFunction builtin (and the associated helper runtime functions) that acts as a trampoline for bound functions. Looking closely into that function, we see that on every possible [[Call]] path through the function (the [[Construct]] path uses the%NewObjectFromBound C++ builtin), we bailout to C++ at least twice, once into%BoundFunctionGetBindings, which returns a new Array with the bound target function, the bound this and the bound arguments, and once into %Apply, which calls back into JavaScript to execute the actual target function with the actual parameters.

Calling into C++ is certainly not fast in V8, but calling back from C++ into JavaScript is very expensive. Also, building one or two temporary Arrays on every invocation of a bound function is not cheap, and can cause unnecessary GC traffic. So, there’s a lot of room for improvement here. I’ve been working on a new approach to implement Bound Function Exotic Objects in V8 for a few months now, as part of a bigger project to fully support objects with [[Call]] and [[Construct]] internal methods that are not ECMAScript Function objects, i.e. to support Proxy Objects. After a lot of yak shaving, I've now reached a point where I’m close to landing my new baseline implementation for Function.prototype.bind.

Running the test program above with my patch requires 239ms for the test loop, which is already a 50x improvement. There’s still some more cleanup to be done in order to land the patch (i.e. some API functions seem to require additional work to deal properly with the new representation of bound function objects), but the baseline results are already very promising. Once the baseline implementation is stabilized, we can start looking into optimizing bound functions, i.e. enable inlining of bound functions—which should boost this particular case to 100x improvement—and properly collecting and dealing with bound function type feedback.

I hope that this will in particular help web sites and web apps using React, because React makes heavy use of Function.prototype.bind. But, for React we will also need to look into the performance of Function.prototype.bind itself and not only the throughput of bound functions, in order to reduce latency and startup time.

Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.

v8 ,chromium ,node.js ,performance ,web dev ,react ,javascript ,c++

Published at DZone with permission of Benedikt Meurer, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.


Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.


{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}