Является ли table.remove () таким же, как p [#p] = nil, и что быстрее? - PullRequest
7 голосов
/ 20 августа 2011

Как следует из названия. Если у меня есть таблица p в lua, используется

table.remove(p)

так же, как

p[#p] = nil

Если так, то это быстрее - я бы предположил второе, но хотел бы получить некоторое заверение.

Под словом «так же, как» я подразумеваю, уменьшается ли внутреннее хранилище массива с помощью присваивания nil? Кажется, я не могу найти это нигде. Означает ли установка для последнего элемента в массиве nil или для последних 10 элементов в массиве nil, массив будет сокращен, или он всегда сохраняет хранилище и никогда больше не сжимает массив?

Я предположил, что массив является смежным, то есть в нем есть значения, хранящиеся в каждой записи массива до # p.

Ответы [ 5 ]

9 голосов
/ 20 августа 2011

Установка последнего элемента на nil не будет вызовом функции. Таким образом, это, безусловно, будет быстрее, чем table.remove. Насколько это важно, зависит от вас.

Под словом «так же, как» я подразумеваю, уменьшается ли внутреннее хранилище массива с помощью присваивания nil? Кажется, я нигде не могу найти это документально.

Это не задокументировано; это позволяет реализации измениться. Все, что обещает Lua, это то, что установка его на nil уменьшит размер, возвращаемый последующими вызовами, до #p. Все, кроме этого, зависит от Lua и может быть изменено без предупреждения. На это не стоит полагаться.

Однако я бы с уважением предположил, что если вы думаете об этих видах микрооптимизации, вам, вероятно, не следует использовать язык сценариев. Язык сценариев должен использоваться для кода, где производительность не настолько важна, чтобы тратить на нее много.

4 голосов
/ 21 августа 2011

p[#p] = nil будет быстрее и идентичен для случая, когда table.remove является последней позицией

В качестве дополнительной заметки table.remove(func_call()) может сделать неожиданные вещи, если вызов функции возвращает несколько значений.

3 голосов
/ 21 августа 2011

Исходя из реализации виртуальной машины Lua 5.1, как описано в Советы по производительности Lua Роберто Иерусалимши (главный архитектор Lua), выделенное хранилище таблицы не изменится, пока в следующий раз таблица не будет переформатирована- и, как говорилось снова и снова, вы действительно не должны думать об этом , если у вас нет данных жесткого профилирования, показывающих, что это серьезная проблема.

Что касается разницы между table.remove(t) и t[#t] = nil, см. мой ответ на В чем разница между `table.insert (t, i)` и `t [# t + 1] = i` .

2 голосов
/ 20 августа 2011

Я думаю, что лучше быть согласованным с добавлением, удаляющим элементы из таблиц типов массивов.table.insert и table.remove делают ваш код непротиворечивым и легче читаемым.

Re: таблицы Lua не изменяет размер таблицы, пока вы не добавите в нее первый новый элемент после ранее удаленных элементов.

1 голос
/ 15 марта 2013

table.remove(p) возвращает значение, которое было удалено.p[#p] = nil ничего не возвращает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...