Производительность Chrome: "стандартные" имена свойств по сравнению с нестандартными

Итак, это интересно... Пока я тестировал производительность setAttribute и обычного свойства, установленного на элементе, я обнаружил странное поведение, которое затем тестировал на обычных объектах и ​​... Это все еще странно!

Итак, если у вас есть объект A = {}, и вы устанавливаете его свойство как A['abc_def'] = 1, или A.abc_def = 1, они в основном одинаковы. Но если вы делаете A['abc-def']= 1 или A['123-def']= 1, то у вас проблемы. Это идет медленнее. Я установил здесь тест: http://jsfiddle.net/naPYL/1/. Все они работают одинаково во всех браузерах, кроме хром. Самое забавное, что для свойства "abc_def" хром на самом деле намного быстрее, чем Firefox и IE, как я и ожидал. Но для "abc-def" он по крайней мере в два раза медленнее.

Итак, что происходит здесь в основном (по крайней мере, из моих тестов), заключается в том, что при использовании "правильного" синтаксиса для свойств (легальный синтаксис C, который вы можете использовать с точными свойствами) - это быстро, но когда вы используете синтаксис, который требует использования скобки (a [...]), тогда у вас проблемы.

Я попытался представить, какие детали реализации будут различать таким образом между двумя режимами, и не могли. Поскольку, как я думаю об этом, если вы поддерживаете эти нестандартные имена, вы, вероятно, переводите все имена в одну и ту же механику, а остальная часть - это просто синтаксис, который компилируется в этот механик. Так. синтаксис и [] должны быть одинаковыми после компиляции. Но, очевидно, что-то здесь происходит наоборот...

Не глядя на исходный код V8, может ли кто-нибудь подумать о действительно удовлетворительном ответе? (Подумайте об этом как о упражнении: -))

Здесь также быстрый пример jsperf.com

Благодаря NDM для примера jsperf!

Edit:

Чтобы уточнить, конечно, я хочу также получить конкретный ответ от реального кода (который я уже нашел), а точнее - причина этого конкретной реализации. Это одна из причин, по которой я просил вас взгляните на это "как упражнение", чтобы посмотреть за техническими и попытайтесь найти причину.

Но я также хотел посмотреть, как работают другие люди в таких случаях. Это может показаться "неопределенным" для некоторых из вас, но очень полезно попробовать и подумать как и другие люди время от времени, или придерживаться их точки зрения. Это улучшает ваши собственные способы мышления.

Ответ 1

Таким образом, объекты JS могут использоваться в двух конфликтующих целях. Они могут использоваться как объекты, но их также можно использовать в качестве хэш-таблиц. Однако то, что быстро и имеет смысл для объектов не так для хэш-таблиц, поэтому V8 пытается угадать, что такое данный объект.

Некоторые знаки, которые пользователь может сообщить, что он хочет, чтобы словарь удалял свойство, или давая свойство имя, к которому нельзя получить доступ с помощью точечной нотации.

Также используются другие эвристики, я сделал gist https://gist.github.com/petkaantonov/6327915.

Однако есть действительно классный взлом, который выкупает объект из хеш-таблицы hell:

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

Смотрите в действии: http://jsperf.com/property-dash-parformance/2.

Искупительный объект не так быстро, как исходный, поскольку свойства хранятся во внешнем массиве свойств, а не в объекте. Но это еще намного лучше, чем хеш-таблица. Обратите внимание, что это по-прежнему довольно сломанный тест, не думайте, что хэш-таблицы всего в 2 раза медленнее, чем свойства объекта.