将表重复传递给函数会分配更多内存吗?

Ian*_*oyd 0 lua garbage-collection unit-testing pass-by-reference

我在Lua中有一个在表上运行的函数,重复向表中添加条目:

function DoStuff()
    local table = {};

    for i = 1, 1000 do
        local name, value = GetSomething(i);

        if (CheckSomething(name, value))
           table[name] = value
        end;
    end;
end;
Run Code Online (Sandbox Code Playgroud)

我知道这很快; Lua有一个很好的哈希表算法.但是现在我需要拆分我的部分功能,所以我可以对它进行单元测试:

function DoStuff()
    local table = {};

    for i = 1, 1000 do
        local name, value = GetSomething(i);

        --split out checking so it's testable
        table = ParseTheThing(table, name, value); 
    end;
end;
Run Code Online (Sandbox Code Playgroud)

我知道Lua不支持通过引用传递参数,相反如果我需要向我添加一个项目table,Lua将复制并且我必须返回该副本:

--Core checking function
function ParseTheThing(table, name, value)
   if (CheckSomething(name, value))
      table[name] = value
   end;

   return table;
end;
Run Code Online (Sandbox Code Playgroud)

所以在我看来,每次调用CheckSomethingLua都会创建另一个表,需要进行垃圾回收.

或者可能不是.也许Lua中确实参考支持传递参数,我可以简单地调用:

ParseTheThing(table, name, value); 

--Core checking function
function ParseTheThing(table, name, value)
   if (CheckSomething(name, value))
      table[name] = value
   end;
end;
Run Code Online (Sandbox Code Playgroud)

如果我像我一样重构我的代码,Lua的垃圾收集器会被迫做更多的工作吗?


备注:

  • 不要混淆问题中使用的简化示例和我问的问题.
  • 我没有办法测量内存使用量或集合数量,所以我无法尝试.

Mud*_*Mud 5

我知道Lua不支持通过引用传递参数

"通过引用"这个术语过载,引起了很多混乱(特别是在Java世界中,我看到人们拒绝承认其中一个含义甚至存在).

通过引用传递可能意味着:

  1. 将对象的位置传递给内存,而不是对象本身.这就是C中"通过引用传递"的含义.从这个意义上讲,Java 确实通过引用传递,Lua的许多类型(用户数据,表等)也是如此.

  2. 变量的别名,以便对别名的任何修改都反映在原始变量中.这不仅仅是不通过价值; 如果变量保存对象的位置,则可以通过别名指定其他位置.你不能为#1做这个,你传递对象的引用,而不是变量.C#,C++等支持这些类型的引用,但不支持C或Lua.

更简单:

  1. 按值传递:调用函数中的对象是被调用函数接收的对象的副本.
  2. 通过引用传递^ 1:调用函数中的对象可以被被调用函数修改.
  3. 通过引用传递^ 2:调用函数中的变量可以被调用函数修改.

相反,如果我需要添加一个项目到我的表

只需传递表格 - 传递参考,而不是副本.

  • 从Lua手册:"表,函数,线程和(完整)userdata值是对象:变量实际上不包含这些值,只是对它们的引用.赋值,参数传递和函数返回总是操纵对这些值的引用;这些操作并不意味着任何形式的复制." (2认同)