Setting prototype properties is much slower in Chrome then other browsers
Reported by
rgerb...@gmail.com,
Nov 18 2016
|
|||||
Issue description
UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.0 Safari/537.36
Steps to reproduce the problem:
Run the following code in Chrome and compare to Safari, Firefox, or Edge.
// code below
var body = {};
for (var i = 0; i < 150; i++){
if (i % 3) {
body['prop' + i] = 42;
} else {
body['method' + i] = function() {}
}
}
function Base() {}
Base.prototype = {};
function run(fn, name) {
var start = performance.now(),
i, total, el;
for(i = 0; i < 1000; i++) {
fn();
}
total = performance.now() - start;
el = document.createElement('div');
el.innerHTML = name + ': ' + total.toFixed(2);
document.body.appendChild(el);
}
function makeClass() {
var ctor = function() {};
var obj = {};
ctor.prototype = Object.create(Base.prototype);
var proto = ctor.prototype, name, fn;
for(name in body){
fn = body[name];
if (typeof fn === 'function') {
fn.$owner = ctor;
fn.$name = name;
}
proto[name] = fn; // What is happening here?
}
return ctor;
}
run(makeClass, 'Class Maker');
What is the expected behavior?
Chrome is running as quickly as other browsers.
What went wrong?
Chrome is slow :( Sometimes even 12x slower :( :(
Did this work before? No
Chrome version: 56.0.2924.0 Channel: canary
OS Version: OS X 10.12.1
Flash Version: Shockwave Flash 24.0 r0
Almost all the time seems to be in the line "proto[name] = fn;"
FYI on my Macbook Pro I am seeing the following numbers
Chrome Version 56.0.2924.0 canary (64-bit) - 511ms
Safari Version 10.0.1 (12602.2.14.0.7) - 43ms
Firefox 50.0 - 83ms
,
Nov 19 2016
This is representative of what goes on loading a large application using a class construction library that operates on prototypes.
,
Nov 19 2016
Saved code as a fiddle - https://jsfiddle.net/hnraoLej/1/ Microsoft Edge crushes it too. Chrome 54.0.2840.99 -- 460.43 MS Edge 25.10586.672.0 -- 39.40 Edge is > 11x faster :( Windows 10.0.10586 Build 10586 32 GB RAM Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz, 3401 Mhz, 4 Core(s), 8 Logical Processor(s)
,
Nov 21 2016
I believe this is regression, started with Chrome 43 - not sure what was changed there. Tested with https://jsfiddle.net/hnraoLej/1/ Chrome 41.0.2272.76 -- 98.00 Chrome 42.0.2311.90 -- 94.00 Chrome 43.0.2357.65 -- 405.00 Chrome 44.0.2403.125 -- 465.00 Chrome 45.0.2454.93 -- 496.00 Windows 10. It's tested using Sauce Labs. Not the best source for the performance tests but I tried to start several virtual machines with 42 and 43 to be sure. This can be huge performance killer if used on large-scale!
,
Nov 22 2016
,
Nov 22 2016
Here are the timings from Embedded Linux with Qt 5.6.1, which initiated the whole investigation: - Qt WebKit: 380 ms - Qt WebEngine (based on Chromium 45): 3400 ms
,
Nov 22 2016
Able to reproduce the issue on windows 7, Linux Ubuntu 14.04 and Mac 10.11.6 using chrome canary 57.0.2926.0 version. Please find the bisect information as below. Narrow Bisect: GOOD-43.0.2313.0-Revision--317570 BAD--43.0.2314.0-Revision--317781 You are probably looking for a change made after 317621 (known good), but no later than 317637 (first known bad). CHANGELOG URL: https://chromium.googlesource.com/chromium/src/+log/ac997d3fdca4aff32e9c80779c 87dfd1e1a8e69b..8cf9caa44a6c41ca1df13a6e764ad430deb26901 Possible suspect: https://chromium.googlesource.com/v8/v8/+/6e346dfc8435114a1c65e259060481c92e43a439 verwaest@could you please look into this issue if it is related to your change,else please route this to an appropriate dev person. Thanks,
,
Nov 22 2016
I'm aware of the issue. By now we should have most infrastructure in place to also make this particular pattern much better. I have a proposed fix (https://codereview.chromium.org/2525573002/) that will make it go from ~400 to ~50ms. We'll have to make sure that this doesn't inadvertently tank performance elsewhere though.
,
Nov 22 2016
The following revision refers to this bug: https://chromium.googlesource.com/v8/v8.git/+/30d2fb6b509f44194ee5a6a7c1caa6b36fa61074 commit 30d2fb6b509f44194ee5a6a7c1caa6b36fa61074 Author: verwaest <verwaest@chromium.org> Date: Tue Nov 22 13:24:53 2016 [runtime] Always normalize prototype maps that aren't marked as 'should be fast' yet This makes the test in the bug ~10x faster. It could inadvertently make other things slower, so revert eagerly if included in a range where performance tanks. BUG= chromium:666852 Review-Url: https://codereview.chromium.org/2525573002 Cr-Commit-Position: refs/heads/master@{#41178} [modify] https://crrev.com/30d2fb6b509f44194ee5a6a7c1caa6b36fa61074/src/objects.cc [modify] https://crrev.com/30d2fb6b509f44194ee5a6a7c1caa6b36fa61074/test/mjsunit/fast-prototype.js
,
Nov 22 2016
And Jakob's CL https://codereview.chromium.org/2504403005 now makes it run in ~17ms. I guess we can close this at ~25x speedup :)
,
Nov 22 2016
Awesome stuff! No we can report bugs on Firefox, Safari and Edge that Chrome is 2x faster! :)
,
Nov 23 2016
Since Qt WebEngine is based on Chromium 45, I am not able to leverage from the huge improvement immediately. Instead, I just reverted the original changes in Chromium 43, which had caused a decrease in performance by >4x as confirmed by verwaest. Here is my change in v8/src/objects.cc line 9802:
//if (mode == FAST_PROTOTYPE && PrototypeBenefitsFromNormalization(object)) {
if (mode == FAST_PROTOTYPE && !object->map()->is_prototype_map()) {
Then I did a complete rebuild of Qt WebEngine.
Unfortunately, I do not see a performance improvement.
Do I miss something in order to backport this fix to Chromium 45?
,
Nov 25 2016
Actually, the commit https://chromium.googlesource.com/v8/v8/+/fade797d02a2c3da305004803eccc45ea9b103e2%5E%21/#F0 had been causing the initial performance bug. After reverting this in my Embedded Linux with Qt 5.6.1, I get the following timings: - Qt WebKit: 380 ms - Qt WebEngine: 3400 ms - Qt WebEngine with fix: 650 ms
,
Nov 28 2016
If you have control over the full stack, you could also just set up the prototype object installing it as prototype of the function. That way you get the best of both.
,
Dec 12 2016
Now I was able to compile the latest Chromium for my Embedded Linux and I get: - Chromium 57.0.2948.0: 200 ms (almost double speed compared to Qt WebKit) |
|||||
►
Sign in to add a comment |
|||||
Comment 1 by dtapu...@chromium.org
, Nov 18 2016