Гибридный массив Lua и хэш-таблица; он существует где-нибудь еще?

реализация Lua таблиц сохраняет свои элементы в двух частях: часть массива и хэш-часть.

существует ли такая вещь в каких-либо других языках?

взгляните на раздел 4, таблицы, в реализация Lua 5.0.

исходный код Lua 5.1 - таблица.c

4 ответов


эта идея была оригинальной с Роберто Ierusalimschy и остальной частью команды Lua. Я слышал, как Роберто говорил об этом на семинаре MIT Lightweight Languages в 2003 году, и в этом разговоре он обсуждал предыдущую работу и убедительно доказывал, что идея была новой. Не знаю, скопировали ли его с тех пор другие языки.

исходный Awk имеет несколько более ограниченную языковую модель, чем Lua; либо число, либо строка могут использоваться в качестве ключа в массиве, но сами массивы не являются первоклассными значениями: массив должен иметь имя, а массив нельзя использовать в качестве ключа в массиве.

Что касается реализации, я проверил источники для исходного Awk, поддерживаемого Брайаном Керниганом, и реализация Awk использует хэш-таблицу, а не гибридную структуру массива/таблицы Lua. Различие важно, потому что в Lua, когда таблица используется с последовательными целочисленными ключами, накладные расходы пространства такие же, как для массива C. Это не true для оригинального Awk.

Я не потрудился исследовать все более поздние реализации awk, например, Gnu Awk, mawk и так далее.


EDIT:это не отвечает на вопрос, который был о реализации.

на awk также сделал это.

интересно, как некоторые языки объединяют операции, которые отличаются в других:

  • список индексации - a[10]
  • ассоциативной индексации - a['foo']
  • доступ к полю объекта - a.foo
  • вызовы функций / методов -a('foo') / a.foo()

очень неполные примеры:

  • Perl-редкий язык, где последовательное / ассоциативное индексирование имеет отдельный синтаксис -a[10] / a{'foo'}. AFAIK, объектные поля сопоставляются с одной из других операций, в зависимости от того, какой реализатор класса хотел использовать.

  • в Python все 4 различны; последовательное / ассоциативное индексирование использует тот же синтаксис, но отдельные типы данных оптимизированы для их.

  • в Ruby поля объектов-это методы без аргументов -a.foo.

  • в JavaScript поля объектов a.foo синтаксис сахара для ассоциативной индексации a['foo'].

  • в Lua и AWK ассоциативные массивы также используются для последовательного индексирования -a[10].

  • на Arc, последовательное и ассоциативное индексирование выглядит как вызовы функций -(a 10) / (a "foo"), и я думаю a.foo синтаксис сахар для этого тоже (?).


самое близкое, что я могу придумать-это JavaScript - вы создаете массив с new Array(), а затем перейдите к индексу по номеру или по строковому значению. Вполне возможно, что по соображениям производительности некоторые реализации Javascript предпочитают делать это с использованием двух массивов по причинам, указанным в документации Lua, с которой вы связаны.


ArrayWithHash - это быстрая реализация гибрида array-hashtable в C++.

поскольку C++ является статически типизированным языком, в ArrayWithHash разрешены только целочисленные ключи (невозможно вставить строку или ключ указателя). Другими словами, это что-то вроде массива с резервной копией хэш-таблицы для больших индексов. Также он использует другую реализацию хэш-таблицы, которая менее эффективна для памяти, чем реализация таблицы Lua.