Nil vs False, memory question

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
MarekkPie
Inner party member
Posts: 587
Joined: Wed Dec 28, 2011 4:48 pm
Contact:

Re: Nil vs False, memory question

Post by MarekkPie »

Rather than check for the non-existence of something (like if there is air above me), try this:

Code: Select all

function Player:collision(...)
  -- if colliding with block
  if not self.onground then self.onground = true end
end

function Player:update(dt)
  if self.onground and love.keyboard.isDown(' ') then
    self.onground = false
    self.velocity.y = -100
  end
end
You're going to need to check if you are on the ground anyways, because otherwise you could just jump in midair constantly.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Nil vs False, memory question

Post by bartbes »

I'd expect "not ==" to be slower than "~=", though not by much. Why? Well, because the former is two operators, while the latter is one, of course, and as far as I know lua doesn't optimize. (It might be noted, that in the __eq case it still does a not, albeit internally, I can't compare the speed of that, I'd say the implicit one is faster as well, but in any case, "~=" should be faster in the average case, that is, without __eq.)
User avatar
Ubermann
Party member
Posts: 146
Joined: Mon Nov 05, 2012 4:00 pm

Re: Nil vs False, memory question

Post by Ubermann »

bartbes wrote:I'd expect "not ==" to be slower than "~=", though not by much. Why? Well, because the former is two operators, while the latter is one, of course, and as far as I know lua doesn't optimize. (It might be noted, that in the __eq case it still does a not, albeit internally, I can't compare the speed of that, I'd say the implicit one is faster as well, but in any case, "~=" should be faster in the average case, that is, without __eq.)
I can do it WITHOUT operators. Read next ^_^


Luska72 wrote:I am currently working on a very basic 2d side-scroller game. My map is nothing more than a 2-d array, and most of that is just air.
I was wondering if I would it would somehow be more 'memory efficient' to change all the 0s in the table to nil (leave them blank).
I could still check if it was an 'air' block with something like:

Code: Select all

Item = level[y][x]
if item ~= nil then
  --draw block and stuff
end

If you want the less possible memory usage, then don't declare a new variable:

Code: Select all

if level[y][x] then
  --draw block and stuff
end
It will enter the If...end when level[y][x] is not nil or false

And when you want to delete that map cell, just do level[y][x] = nil
User avatar
veethree
Inner party member
Posts: 877
Joined: Sat Dec 10, 2011 7:18 pm

Re: Nil vs False, memory question

Post by veethree »

MarekkPie wrote:Rather than check for the non-existence of something (like if there is air above me), try this:

Code: Select all

function Player:collision(...)
  -- if colliding with block
  if not self.onground then self.onground = true end
end

function Player:update(dt)
  if self.onground and love.keyboard.isDown(' ') then
    self.onground = false
    self.velocity.y = -100
  end
end
You're going to need to check if you are on the ground anyways, because otherwise you could just jump in midair constantly.
Quick question, What does the "self" variable actually represent? I've seen that before in some camera lib i got from somewhere and don't recall seeing it defined anywhere..
User avatar
Ubermann
Party member
Posts: 146
Joined: Mon Nov 05, 2012 4:00 pm

Re: Nil vs False, memory question

Post by Ubermann »

veethree wrote:
MarekkPie wrote:Rather than check for the non-existence of something (like if there is air above me), try this:

Code: Select all

function Player:collision(...)
  -- if colliding with block
  if not self.onground then self.onground = true end
end

function Player:update(dt)
  if self.onground and love.keyboard.isDown(' ') then
    self.onground = false
    self.velocity.y = -100
  end
end
You're going to need to check if you are on the ground anyways, because otherwise you could just jump in midair constantly.
Quick question, What does the "self" variable actually represent? I've seen that before in some camera lib i got from somewhere and don't recall seeing it defined anywhere..

http://lua-users.org/wiki/SimpleLuaClasses

"self" is a reference to the class itself.
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Nil vs False, memory question

Post by micha »

veethree wrote:
MarekkPie wrote:Rather than check for the non-existence of something (like if there is air above me), try this:

Code: Select all

function Player:collision(...)
  -- if colliding with block
  if not self.onground then self.onground = true end
end

function Player:update(dt)
  if self.onground and love.keyboard.isDown(' ') then
    self.onground = false
    self.velocity.y = -100
  end
end
You're going to need to check if you are on the ground anyways, because otherwise you could just jump in midair constantly.
Quick question, What does the "self" variable actually represent? I've seen that before in some camera lib i got from somewhere and don't recall seeing it defined anywhere..
The above function Player:update(dt) operates on an object, namely a player. This function can be recycled and used also, if you have multiple players. Then everytime all the operations act on a different object (a different player). So instead of writing two function update1 nad update2 you pass the corresponding player as an argument, which is then called self in the function. That means that if you call player1:update(dt) then self refers to player1 and if you call mario:update(dt) then self refers to mario (provided player1 and mario exist).

The self-notation is so-called syntactic sugar. That means it's just a short way of writing something, which is a bit longer if written out.

This is only a rough explanation, please read this here: http://www.lua.org/pil/16.html
By the way, I suggest you also read the rest of the book. It's good.
User avatar
veethree
Inner party member
Posts: 877
Joined: Sat Dec 10, 2011 7:18 pm

Re: Nil vs False, memory question

Post by veethree »

micha wrote:
veethree wrote:
MarekkPie wrote:Rather than check for the non-existence of something (like if there is air above me), try this:

Code: Select all

function Player:collision(...)
  -- if colliding with block
  if not self.onground then self.onground = true end
end

function Player:update(dt)
  if self.onground and love.keyboard.isDown(' ') then
    self.onground = false
    self.velocity.y = -100
  end
end
You're going to need to check if you are on the ground anyways, because otherwise you could just jump in midair constantly.
Quick question, What does the "self" variable actually represent? I've seen that before in some camera lib i got from somewhere and don't recall seeing it defined anywhere..
The above function Player:update(dt) operates on an object, namely a player. This function can be recycled and used also, if you have multiple players. Then everytime all the operations act on a different object (a different player). So instead of writing two function update1 nad update2 you pass the corresponding player as an argument, which is then called self in the function. That means that if you call player1:update(dt) then self refers to player1 and if you call mario:update(dt) then self refers to mario (provided player1 and mario exist).

The self-notation is so-called syntactic sugar. That means it's just a short way of writing something, which is a bit longer if written out.

This is only a rough explanation, please read this here: http://www.lua.org/pil/16.html
By the way, I suggest you also read the rest of the book. It's good.
Dude i gotta read more. Never knew that.
User avatar
MarekkPie
Inner party member
Posts: 587
Joined: Wed Dec 28, 2011 4:48 pm
Contact:

Re: Nil vs False, memory question

Post by MarekkPie »

micha wrote:The self-notation is so-called syntactic sugar. That means it's just a short way of writing something, which is a bit longer if written out.
self isn't the syntactic sugar, the colon (:) operator is the syntactic sugar, which causes self to represent...itself. Here's a more robust example:

Code: Select all

local Player = {}
Player.__index = Player

function Player:new(name)
  return setmetatable({
    name = name
  }, self)
end

--- Dot notation declaration
-- I can call the first parameter anything, because I am explicitly declaring it
function Player.foo1(player, bar)
  print(player.name, bar)
end

--- Colon notation declaration
-- I can only refer to fields of the current object using self, because it is implied to
-- be the name of the first parameter
function Player:foo2(bar)
  print(self.name, bar)
end

local p = Player:new("Michael")

Player.foo1(p, "Dot notation foo1")
-- prints "Michael Dot notation foo1"

p:foo1("Colon notation foo1")
--prints "Michael Colon notation foo1"

Player.foo2(p, "Dot notation foo2")
-- prints "Michael Dot notation foo2"

p:foo2("Colon notation foo2")
-- prints "Michael Colon notation foo2"
When declaring a function, the colon (:) forces you to use self to refer back to the calling object, but otherwise performs essentially the same as if you declared the first parameter yourself using the dot (.) notation.

When invoking the functions, the first two are the same call, as well as the second two (albeit with different bar parameters). All the colon (:) notation does is transplant the object you are using to call the function into the first (hidden) parameter, called self.

You can also see that regardless of how I declared the functions, when I invoke them, I can use either notation to achieve the same result. I would bet, however, that the more Lua-like way would be to use the colon (:) notation when using tables as objects, and the dot (.) notation when using tables as namespaces.

(You probably knew this, but it might be a bit confusing for someone new to Lua's object orientation.)
User avatar
Xgoff
Party member
Posts: 211
Joined: Fri Nov 19, 2010 4:20 am

Re: Nil vs False, memory question

Post by Xgoff »

Beta Carotene wrote:One thing I do remember is that, under normal circumstances, lua will not shrink the memory that's already allocated to a table, so you need to make sure that those empty spaces never get allocated in the first place (as opposed to creating all of them, then running back through and setting them all to nil).
it will, but only when it rehashes the table (which itself is only performed if enough new entries are added)

in any case, by using a scripting language you're kinda implying you don't care so much about optimal memory use lol
Beta Carotene
Prole
Posts: 7
Joined: Thu Jan 17, 2013 11:28 pm

Re: Nil vs False, memory question

Post by Beta Carotene »

Xgoff wrote:
Beta Carotene wrote:One thing I do remember is that, under normal circumstances, lua will not shrink the memory that's already allocated to a table, so you need to make sure that those empty spaces never get allocated in the first place (as opposed to creating all of them, then running back through and setting them all to nil).
it will, but only when it rehashes the table (which itself is only performed if enough new entries are added)

in any case, by using a scripting language you're kinda implying you don't care so much about optimal memory use lol
Well sure, but I think it can affect your performance overall though. I recently went back and did a lot of optimizations to a very intensive piece of script code. With roughly 2,500 actors it was using roughly 65 MB, and was starting to drag heavily. After working on it for about 2 days and testing that bugs hadn't been created, it had reduced to roughly 8 MB and my performance was doing fine. It's certainly less important in script than it is in a low level language, but it can still hurt you if you become careless (like I was with the 65 MB thing).

To the OP, if your world gets large enough, you should keep in mind little things like that which could eat your memory quickly (and be working the garbage collector too hard). I think you're right to be thinking ahead about these things. Just remember, always get it working first, then optimize later (except if the optimizations are like... dead obvious and don't make code harder to read).
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest