2013-09-27 13 views
12

To jest interesujące ... Podczas testowania wydajności setAttribute vs. normalnego ustawienia właściwości elementu, znalazłem dziwne zachowanie, które następnie testowane na zwykłych obiektach i ... To wciąż dziwne!Wydajność Chrome: "standardowe" nazwy właściwości w stosunku do niestandardowych

Więc jeśli masz obiektu A = {}, i ustawić jego właściwość jak A['abc_def'] = 1 lub A.abc_def = 1, są w zasadzie takie same. Ale jeśli zrobisz A['abc-def'] = 1 lub A['123-def'] = 1, masz kłopoty. To idzie trochę wolniej. Przygotowałem test tutaj: http://jsfiddle.net/naPYL/1/. Wszystkie działają tak samo we wszystkich przeglądarkach oprócz chrome. Zabawne jest to, że dla właściwości "abc_def", chrome jest w rzeczywistości dużo szybsze niż Firefox i IE, tak jak się spodziewałem. Ale w przypadku "abc-def" jest co najmniej dwa razy wolniej.

To, co dzieje się tutaj (przynajmniej z moich testów), polega na używaniu "poprawnej" składni dla właściwości (prawna składnia C, której można używać z właściwościami kropek) - Jest szybka, ale gdy używa się składni, która wymaga używając nawiasów klamrowych ([...]) masz kłopoty.

Próbowałem sobie wyobrazić, jaki szczegół wdrożenia rozróżniałby w taki sposób między dwoma trybami i nie mógł. Ponieważ, jak o tym myślę, jeśli obsługujesz te niestandardowe nazwy, prawdopodobnie tłumaczysz wszystkie nazwy na tę samą mechanikę, a reszta to po prostu składnia, która jest wkompilowana w tę mechanikę. Więc . Składnia i [] powinny być takie same po kompilacji. Ale oczywiście coś tu idzie inaczej ...

Nie patrząc na kod źródłowy V8, czy ktoś mógłby pomyśleć o naprawdę satysfakcjonującej odpowiedzi? (Pomyśl o tym jak o ćwiczenia :-))

Here's also a quick jsperf.com example

Dzięki NDM na jsperf przykład!

Edit:

celu wyjaśnienia, oczywiście chcę też konkretnej odpowiedzi od prawdziwych kodu (który ja już znalezionego) lub dokładniej - z powodu za tym konkretnej implementacji. Jest to jeden z powodów, dla których poprosiłem cię o sprawdzenie "jako ćwiczenia", aby spojrzeć za techniczne wdrożenie i spróbować znaleźć przyczynę.

Ale ja też chciałem zobaczyć, jak umysły innych ludzi działają w takich przypadkach. Może to wydawać się "niejasne" dla niektórych z was - ale bardzo przydatna jest próba od czasu do czasu zastanowienia się, jak inne osoby, lub z ich punktu widzenia. To wzmacnia własne sposoby myślenia.

+4

Niesamowite pytanie. V8 ma mechanizm klasy backing, który spróbuje sparować standardową klasę C++ z obiektami, aby przyspieszyć działanie. Wydaje się, że w rzeczywistości, gdy składnia jest niestandardowa, nie można zbudować tej klasy, więc Chrome obsługuje ją w standardowy sposób (najprawdopodobniej tablica hash). – GameAlchemist

+1

Dodałem test jsperf i połączyłem go z pytaniem. FYI na moim chromie było o 6% wolniejsze. W FF były równie szybkie, ale 7 razy szybsze od chromu! – NDM

+1

Myślę, że to pytanie jest zagrożone zamknięciem, głównie ze względu na * "bez patrzenia na kod źródłowy V8 [...] myśl o nim jako o ćwiczeniu" *. Jest to interesujące pytanie, ale ta linia zachęca do spekulacji zamiast konkretnych odpowiedzi, a to generalnie nie jest mile widziane. –

Odpowiedz

5

Obiekty JS mogą być używane do dwóch sprzecznych celów. Mogą być używane jako obiekty, ale mogą być również używane jako tabele mieszania. Jednak to, co jest szybkie i ma sens, w przypadku obiektów nie jest takie, jak w tabelach mieszających, więc V8 próbuje odgadnąć, czym jest dany obiekt.

Niektóre znaki, które użytkownik może dać, że chce, aby słownik usuwał właściwość lub giving a property a name that cannot be accessed using dot notation.

Stosuje się również inne heurystyki, wykonałem istotę https://gist.github.com/petkaantonov/6327915.

Istnieje jednak a really cool hack że redempts obiektu z tablica mieszająca piekła:

function ensureFastProperties(obj) { 
    function f() {} 
    f.prototype = obj; 
    return obj; 
} 

Zobacz go w akcji: http://jsperf.com/property-dash-parformance/2.

Wykupiony obiekt nie jest tak szybki jak oryginał, ponieważ właściwości są przechowywane w zewnętrznej tablicy właściwości, a nie w obiekcie. Ale to wciąż dużo lepsze niż tablica hash. Zauważ, że jest to nadal bardzo zepsuty test porównawczy, nie myśl przez sekundę, że tablice hash są tylko 2x wolniejsze niż właściwości inobject.

+0

Chłodny hack nie działa w 'Chrome 30.0.1599.65 beta-m' – C5H8NNaO4

+0

@ C5H8NNaO4 tak trzeba zbadać ... kod do optymalizacji obiektu w prototypie jest nadal dostępny nawet na najbardziej krwawiących krawędziach v8 – Esailija

Powiązane problemy