Any difference in performance? [more details inside]

Hey guys, 

As a lua newbie, my question is:

Is there any difference in performance between the 2 methods of copying a table?

Method 1:

[lua]

local table={}

local tmpTable

– copy table to tmpTable

tmpTable=table

[/lua]

Method 2:

[lua]
        for i=1 , rows do

            for j=1 , cols do

                tmpTable[i][j]=table[i][j]

            end

        end
[/lua]

While I know the difference (if exists) should be small, but since I do it so often in my game I would like to choose the better method.

Roy.

First is faster, but remember that this 2 methods are totaly different!

Let’s assume that your table contains only numbers and strings (not tables, functions etc)
 

First one:

create ‘table’ and reserve place in memory for it - let’s call this address 0x11111

create variable ‘tmpTable’

assign to ‘tmpTable’ address 0x1111 in memory pointing to ‘table’ (adress, because tables are passed by reference, not as a copy)

What you have here is called ‘shallow-copy’

[lua]

local table = {}

local tmpTable 

tmpTable = table

–if you now do

table.prop= 2

–then tmpTable will also have property ‘prop’

print(tmpTable.prop) – this will give you ‘2’ in terminal because both variables are referencing to the same object

[/lua]

In the second one when you copy it this way, only table.prop will be ‘2’ an there will be no ‘prop’ property in tmpTable

It’s called “deep-copy” because you are copying by values and numbers and strings are not passed by it’s address in memory but only it’s value

As @piotrz55 said, they’re completely different. Weeding out all the “programmer talk” that I can, here’s the explanation:

Because tables can get pretty big (at least I think that’s why), the creators of Lua decided that for tables, any extra references to them would be made by  reference , not  value. This means that modifying a “copy” of a table (created with local otherTable = originalTable) also modifies the original table. Example:

[lua]

local originalTable = {

  val1 = 110,

  val2 = 500

}

local copyTable = originalTable

copyTable.val1 = 0 – This modifies both tables!

print(originalTable.val1) --> 0

[/lua]

The only way to get a full copy of a table, without references to the original table, is to iterate through the whole thing and copy each value individually into the second table. If you want to do that, you also have to do each inner table, userdata, function, and thread (if you use any of that) because they’re all pass-by-reference objects, too - they’re behavior is identical to a table’s behavior when creating copies and editing them.

  • Caleb

My bad, “programmer talk” still showing, silly me :P (I don’t know why, but always knowing details was better learning experience for me)

:slight_smile:

Thank you guys for your detailed answers!
I now know the difference between the methods.

Cheers!
Roy.

To add, remember that if you want to free memory which table occupiess, you must nil both originalTable and copyTable (only in case when you just do local copyTable = originalTable). This is how Lua works with garbage collecting - lua can only collect items to which nothing is pointing.

First is faster, but remember that this 2 methods are totaly different!

Let’s assume that your table contains only numbers and strings (not tables, functions etc)
 

First one:

create ‘table’ and reserve place in memory for it - let’s call this address 0x11111

create variable ‘tmpTable’

assign to ‘tmpTable’ address 0x1111 in memory pointing to ‘table’ (adress, because tables are passed by reference, not as a copy)

What you have here is called ‘shallow-copy’

[lua]

local table = {}

local tmpTable 

tmpTable = table

–if you now do

table.prop= 2

–then tmpTable will also have property ‘prop’

print(tmpTable.prop) – this will give you ‘2’ in terminal because both variables are referencing to the same object

[/lua]

In the second one when you copy it this way, only table.prop will be ‘2’ an there will be no ‘prop’ property in tmpTable

It’s called “deep-copy” because you are copying by values and numbers and strings are not passed by it’s address in memory but only it’s value

As @piotrz55 said, they’re completely different. Weeding out all the “programmer talk” that I can, here’s the explanation:

Because tables can get pretty big (at least I think that’s why), the creators of Lua decided that for tables, any extra references to them would be made by  reference , not  value. This means that modifying a “copy” of a table (created with local otherTable = originalTable) also modifies the original table. Example:

[lua]

local originalTable = {

  val1 = 110,

  val2 = 500

}

local copyTable = originalTable

copyTable.val1 = 0 – This modifies both tables!

print(originalTable.val1) --> 0

[/lua]

The only way to get a full copy of a table, without references to the original table, is to iterate through the whole thing and copy each value individually into the second table. If you want to do that, you also have to do each inner table, userdata, function, and thread (if you use any of that) because they’re all pass-by-reference objects, too - they’re behavior is identical to a table’s behavior when creating copies and editing them.

  • Caleb

My bad, “programmer talk” still showing, silly me :P (I don’t know why, but always knowing details was better learning experience for me)

:slight_smile:

Thank you guys for your detailed answers!
I now know the difference between the methods.

Cheers!
Roy.

To add, remember that if you want to free memory which table occupiess, you must nil both originalTable and copyTable (only in case when you just do local copyTable = originalTable). This is how Lua works with garbage collecting - lua can only collect items to which nothing is pointing.