【问题标题】:Optimized Lua Table Searching优化 Lua 表搜索
【发布时间】:2021-02-17 16:17:40
【问题描述】:

我有一个 LUA 表:

local tableDatabase = {
  name = uniqueName,
  class = val_one_to_eight,   --not unique
  value = mostly_but_not_guaranteed_unique_int}

此表可以按以上任何一项排序,并且可能包含非常大的数据集。

现在为了插入,我只是遍历表 ipairs,直到找到:

 insertedvalue.uniqueName > tableDatabase.uniqueName
 --(or comparing the other parms instead if they are the selected sort order.)

我需要这个功能超快地工作。是否有人可以推荐一种搜索算法来查找要插入的表中的索引,或者我可以使用某种可以在 lua 表上工作以优化插入速度的方法?

【问题讨论】:

    标签: search lua lua-table


    【解决方案1】:

    据我所知,对于严格有序的结构,您可以使用二进制搜索或类似的算法。 Lua 用户provides 准备使用功能。

    【讨论】:

      【解决方案2】:

      为什么不在name 上创建索引?如果速度不够快,您可以使__index 不那么通用,即硬编码name 上的唯一索引。

      -- Returns a table. ... is a list of fields, for which unique indices should be created:
      function indexedTable (...)
          local t = {
              __indices = {},
              __insert = function (self, value)   -- instead of table.insert.
                  self [#self + 1] = value    -- implicily calls metamethod __newindex.
              end     
          }
          -- Initialise indices:
          for _, index in ipairs {...} do
              t.__indices [index] = {}
          end
          setmetatable (t, {
              -- Allow t [{name = 'unique'}]:
              __index = function (t, key)
                  if type (key) == 'table' then
                      for index_key, index_value in pairs (key) do
                          local value = t.__indices [index_key] [index_value]
                          if value then
                              return value
                          end
                      end
                  else
                      return rawget (t, key)
                  end
              end,
              -- Updates all indices on t [k] = v, but doesn't work on table.insert, so use t:__insert"
              __newindex = function (t, key, value)
                  -- insert uniqueness constraint here, if you want.
                  for index_key, index in pairs (t.__indices) do
                      index [value [index_key]] = value
                  end
                  rawset (t, key, value)
              end
          })
          return t
      end
      
      -- Test:
      
      local tableDatabase = indexedTable ('name')
      
      -- Not table.insert, as it is not customizable via metamethods:
      tableDatabase:__insert {
          name    = 'unique1',
          class   = 1,
          value   = 'somewhat unique'
      }
      
      tableDatabase:__insert {
          name    = 'unique2',
          class   = 2,
          value   = 'somewhat unique'
      }
      
      tableDatabase:__insert {
          name    = 'unique3',
          class   = 2,
          value   = 'somewhat unique but not absolutely'
      }
      
      local unique2 = tableDatabase [{name = 'unique2'}]  -- index search.
      print (unique2.name, unique2.class, unique2.value)
      

      【讨论】:

      • 这样做有什么好处?这看起来像开销哈希搜索。它只是使用给定的 key = value 搜索条目并返回。
      • 这有几个问题。名称不是表可以排序的唯一参数。它可以按上述任何字段排序。当我求助时,我基本上必须重新索引整个表。那我不确定这会比我目前正在做的更有效率。
      • @user3758015,恐怕我不明白你的评论。在我的解决方案中,我根本不对表格进行排序。我创建了一个或多个直接指向表项(也是表)的索引,并且它们不需要对表排序、插入或删除进行重新组织。我的解决方案的局限性在于它只处理由一个字段组成的唯一索引。
      猜你喜欢
      • 2021-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-14
      • 2015-07-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多