2016-03-31 3 views
2

BeiObjektdeskriptorabschnitt Getter/Setter Leistung in der letzten Chrome/V8-Versionen

var obj = {}; 

var _a = 1; 

obj._a = 1; 

obj.aGetter = function() { 
    return _a; 
} 

obj.aSetter = function(val) { 
    _a = val; 
} 

Object.defineProperty(obj, 'a', { 
    enumerable: true, 
    get: function() { 
    return _a; 
    }, 
    set: function(val) { 
    _a = val; 
    }  
}); 

mit Getter/Setter-Funktionen

obj.aSetter(2); 
obj.aGetter(); 

wird einigen Rückgang in Chrom/V8 Leistung hat (~ 3x) im Vergleich Direkten Eigentumszugang:

obj._a = 2; 
obj._a; 

Dies ist verständlich. Und Setter mit Descriptor Getter/

obj.a = 2; 
obj.a; 

verursacht ~ 30x Abnahme in Chrome (41 bis spätestens) Leistung - fast so langsam wie Proxy. Während Firefox und ältere Chrome-Versionen Deskriptor-Getter/Setter ohne signifikante Leistungseinbußen verwenden.

Was ist das genaue Problem mit der Deskriptor Getter/Setter-Leistung in den letzten Chrome/V8-Versionen? Ist es ein bekanntes Problem, das überwacht werden kann?

Die Messungen wurden mit Benchmark.js (jsPerf engine) durchgeführt. Ich kann keine Verbindung zum jsPerf-Test herstellen, um den Unterschied zu visualisieren, weil jsPerf mit seinen Anti-DDoS-Maßnahmen ernsthaft vermasselt wurde, aber ich bin sicher, dass es existierende gibt, die einen Punkt beweisen können.

+0

Wie die alten Chrome-Versionen vergleichen in den direkten Zugang zu den neuen - sind sie schneller geworden, oder die Leistung Accessor wirklich verringert:

um Leistungsprobleme zu vermeiden, sollte ein Prototyp stattdessen verwendet werden? – Bergi

+0

Afaik, Getter/Setter sind nicht gut in V8 optimiert. – Bergi

+0

@Bergi Deskriptor-Accessoren scheinen in GC <= 39 recht gut optimiert zu sein (die Objekteigenschaften schneiden nicht so gut ab wie in FF, aber trotzdem). Aber etwas hat sich in 41 geändert (GC 40, um es zu überprüfen), das ist der lächerlichste Teil. – estus

Antwort

1

Die Änderungen in der Leistung sind relevant für this Chromium issue (Kredite gehen zu @VyacheslavEgorov).

var _a = 1; 

function Obj() {} 

Object.defineProperty(Obj.prototype, 'a', { 
    enumerable: true, 
    get: function() { 
    return _a; 
    }, 
    set: function(val) { 
    _a = val; 
    }  
}); 

var obj = new Obj(); 
// or 
var obj = Object.create(Obj.prototype); 
Verwandte Themen