Эффективное подсчет количества ключей/свойств объекта в JavaScript

Этот вопрос почти идентичен Как эффективно подсчитывать количество ключей/свойств объекта в JavaScript?.

Я хочу узнать одну дополнительную информацию: что такое постоянный способ определения количества ключей в объекте? В основном я занимаюсь этим в Node.JS, так как большинство объектов в браузере не слишком велики, чтобы вызывать большую озабоченность.

EDIT: Похоже, что Object.keys(obj).length возвращается в линейном времени O (n) в Google Chrome и в Node.JS(т.е. Зависит от количества клавиш в obj). Есть ли лучший метод O (1)?

Я провел некоторое тестирование в Node.JS(источник ниже)

var tests = [10e3, 10e4, 10e5, 10e6]
for(j in tests) {
    var obj = {};
    for(i = 0; i < tests[j]; i++)
        obj[i] = i;
    console.time('test' + tests[j]);
    Object.keys(obj).length;
    console.timeEnd('test' + tests[j]);
}

При n = 10e3, 10e4, 10e5, 10e6... результаты:

test10000: 5ms
test100000: 20ms
test1000000: 371ms
test10000000: 4009ms

Ответы

Ответ 1

См. источник, в частности GetLocalElementKeys

v8 objects.cc

Ответ 2

После небольшого исследования невозможно определить количество ключей в объекте JavaScript в постоянное время, по крайней мере, не в Node... и еще не совсем. Node внутренне отслеживает эту информацию, но не раскрывает ее, поскольку в ECMA-262 5th нет способа сделать это.

Стоит отметить, что Harmony (ECMA версии 6) может поддерживать карты и наборы. Не уверен, что спецификация для них окажется.

Мне сказали, что нам нужно обсудить это с комитетом TC39.

Отчет об ошибке для V8: http://code.google.com/p/v8/issues/detail?id=1800

Ответ 3

Гармония ECMA 6 вводит классы Map и Set, которые вы, вероятно, можете использовать (в будущем:)

var map = new Map;
map.set('a', 'b');
console.log(map.size); // prints 1

Я считаю, что он должен иметь сложность O (1), но не пробовал. Вы можете запустить его в node 0.11+ с помощью node --harmony script.js.


Другой способ - использовать класс Proxy, который также был добавлен в гармонии.