#php #javascript #arrays #map #associative
#php #javascript #массивы #словарь #ассоциативный
Вопрос:
Я новичок в JavaScript и в последнее время кодирую на PHP, который я хочу перенести на JavaScript. PHP Map
реализован непосредственно в своем Array
классе container, который не существует на языке JavaScript по умолчанию.
Все, кого я, кажется, читал, говорят использовать объект для ассоциативного массива, но после прочтения этого, в частности:
Поиск свойств
При доступе к свойствам объекта JavaScript будет проходить цепочку прототипов вверх, пока не найдет свойство с запрошенным именем.
Когда он достигает вершины цепочки, а именно Object.prototype, и все еще не нашел указанное свойство, вместо этого он вернет значение undefined.
Казалось бы, Object
это неэффективное решение для ассоциативных массивов, особенно когда ваш массив желаний может содержать 10 из 1000.
Какова эффективная альтернатива map / ассоциативному массиву в JavaScript? Есть ли хорошая сторонняя библиотека, которая предлагает отличный класс контейнера, реализованный как map / assoc. массив? Мне нужно иметь возможность легко и эффективно создавать большие ассоциативные массивы различной степени для различных стратегий индексирования в моем коде, поэтому мне нужны оптимальные алгоритмы сортировки и поиска.
Простите меня, если все это кажется очевидным, но все указывает мне на реализацию моего assoc. массив как объект, и я считаю, что это не самый оптимальный подход. Любая помощь и указания высоко ценятся.
Комментарии:
1. Это действительно зависит от браузера. Современные браузеры оптимизированы. IE6 работает чертовски медленно
2. Я должен был уточнить, что это для серверного JavaScript в Node.js фреймворк (использующий движок JavaScript версии 8). Что приводит к большому количеству логического кода, который обычно выполняется не в браузере, а в качестве сетевой службы.
3. в таком случае не стоит недооценивать V8. Никогда не стоит недооценивать V8. Используйте объект, массив или связанный список в зависимости от того, как вы используете тип данных (связанные списки отлично подходят для дешевого удаления).
4. Я должен также отметить, что мне критически важна многомерная функциональность, иногда шириной до 4 ключей. В некоторых случаях я ищу один или два первых ключа, а другие я сохраняю для поиска / сопоставления всех ключей (очевидно, всегда для вставки).
Ответ №1:
Цитата в вашем вопросе действительно не имеет ничего общего с тем, насколько оптимизирован поиск свойств. Когда вы сделаете это: var x = {}
и затем x.foo
, он проверит, существует ли foo . Если это не так, то он не будет «подниматься по цепочке» и искать в другом месте, потому что x
это уже самый примитивный тип объекта.
О чем вы действительно спрашиваете, так это о том, насколько оптимизирован поиск строки, учитывая, что у вас есть объект. Тем не менее, проверьте это:
http://www.timdown.co.uk/jshashtable/
Это реализация хэш-таблицы в JS. Я не проверял, насколько это было оптимизировано, но в Chrome это было в 5-10 раз медленнее, чем просто использование обычных объектов JS в качестве хэш-таблицы. (Размер теста 10000 элементов.) Я сам написал простую хэш-таблицу JS и получил такие же результаты.
Я бы предположил, но, очевидно, вам следует это проверить, что все браузеры реализуют строковые ключи как оптимизированный хэш внутри, очень похоже на то, как будет работать PHP array. Было бы довольно глупо, если бы это было не так, с точки зрения производительности.
Комментарии:
1. Зачем вам хэш-таблица: ( у вас есть объекты. Если вы создали связанный список, то достаточно справедливо
2. @Raynos, у хэш-таблицы на основе JS есть некоторые преимущества. Автор объясняет это по предоставленной ссылке, но скорость не входит в их число. OP просто беспокоился, что поиск свойств собственного объекта не был оптимизирован.
3. Спасибо за ссылку, я проверю это 🙂 Я переношу код для использования в качестве серверного JavaScript в Node.js фреймворк (движок Google JavaScript v8), поэтому производительность и оптимальная сортировка и поиск по ключам будут наиболее важны. Вся моя кодовая база зависит от многоуровневых карт для внутренних списков и кэширования данных. Если JavaScript на стороне сервера не показывает promise, я буду вынужден кодировать на C: p
4. Поскольку это серверная часть, это упростит ваши тесты. Я предполагаю, что производительность V8 будет не хуже, чем у чего-то вроде PHP при работе с хэш-таблицей объектов.
5. jshashtable спроектирован так, чтобы быть гибким, что достигается ценой некоторой производительности. Это могло бы быть оптимизировано для конкретных случаев (например, ограничение ключей только строками), но это привело бы к раздуванию кода. В любом случае, лучшее, на что он может надеяться в своем текущем виде, — это соответствовать производительности поиска свойств собственного объекта JavaScript.
Ответ №2:
Поскольку Object
это самая верхняя prototype
часть цепочки (вы не используете подобъекты с подпрототекстами), цепочки для оценки нет. Таким образом Object.prototype
, это единственный прототип, к которому он будет обращаться для проверки свойств. Таким образом, на самом деле такой проблемы, как вы подразумевали в цитате, не существует.
Комментарии:
1. Итак, реализуем объект, содержащий 100 000 свойств (ключ / значение), чтобы иметь assoc. поведение массива является оптимальным подходом в JavaScript? Когда я ищу определенный «ключ», будет ли он использовать оптимальный двоичный поиск (или другой оптимизированный алгоритм)? Всегда ли будут отсортированы эти ключи? Из того, что я прочитал по ссылке о свойствах, они находятся путем последовательного поиска запрошенного свойства.
2. @j_p это не ассоциативный массив. Объекты не имеют порядка. Это просто неупорядоченная хэш-таблица. Это не бинарный поиск, это время поиска O (1). Либо используйте хэш-таблицу (object), массив (array), либо связанный список (implementate one)
3. Я не говорил, что это лучший способ, просто это не такой плохой способ, как вы подразумевали (или я думаю, что ваша мысль). Я не уверен в деталях реализации, но это самый простой способ сделать это. Райнос уже рассказал некоторые подробности о «внутренностях».