ProjectsWhat's NewDownloadsCommunitySupportCompany
Forum Index » S.T.A.L.K.E.R.: Shadow of Chernobyl Forum » Mod discussion
Script optimization question

1 2 3 4 | Next 10 events »| All Messages
Posted by/on
Question/AnswerMake Newest Up Sort by Descending
  22:46:56  28 January 2013
profilee-mailreply Message URLTo the Top
Decane
Senior Resident
 

 
On forum: 04/04/2007
 

Message edited by:
Decane
01/28/2013 22:57:38
Messages: 1701
Script optimization question

Of the following codes, which is fastest and why?

(A1)

local act = db.actor
function test()
  if not has_alife_info("tester") then
    if IsStalker(act) then
      act:give_info_portion("tester")
    end
  end
end


(A2)

function test()
  local act = db.actor
  if not has_alife_info("tester") then
    if IsStalker(act) then
      act:give_info_portion("tester")
    end
  end
end


(B1)

local act = db.actor
function test()
  if not has_alife_info("tester") and IsStalker(act) then
    act:give_info_portion("tester")
  end
end


(B2)

function test()
  local act = db.actor
  if not has_alife_info("tester") and IsStalker(act) then
    act:give_info_portion("tester")
  end
end


Apart from remarks relating to the stuff above, other optimization tips are also welcome.

EDIT: Also, which of these is faster?

if db.actor then
...


if db.actor ~= nil then
..


Or are they equally fast?

All this is strictly theoretical speed, by the way; I know that in practice the difference will be negligible.
  23:05:12  28 January 2013
profilee-mailreply Message URLTo the Top
ThunderFreak
Senior Resident
 

 
On forum: 08/07/2009
Messages: 685
I would say version A2 is fastest.

Why?
Local variable declarations are faster than global declarations. Which means local declaration outside a function block are not belonging to a function in first place. Those variables need to be indexed.
Declarations within a function block are directly belonging to that function block. No need to index them.
To call an indexed variable causes to search thru the index, which takes time. To call a variable directly causes no time.

'AND' operations are quite slow, so it's better to two 'if'-conditions in two lines rather than in in one line linked with 'AND'.

Hope you understand what I mean.
  00:08:09  29 January 2013
profilee-mailreply Message URLTo the Top
SetaKat
Ex modder, Zones only ferret and will someday release a game
(Resident)

 

 
On forum: 02/20/2010
Messages: 6340
Thanks for that info on 'and' operators being slow, will remove them from my own scripts now, should get a speed boost.
  00:43:15  29 January 2013
profilee-mailreply Message URLTo the Top
Decane
Senior Resident
 

 
On forum: 04/04/2007
Messages: 1701

---QUOTATION---
Local variable declarations are faster than global declarations. Which means local declaration outside a function block are not belonging to a function in first place. Those variables need to be indexed.
Declarations within a function block are directly belonging to that function block. No need to index them.
To call an indexed variable causes to search thru the index, which takes time. To call a variable directly causes no time.

'AND' operations are quite slow, so it's better to two 'if'-conditions in two lines rather than in in one line linked with 'AND'.
---END QUOTATION---


Interesting; thanks for replying.

Now what about these two?

(A1)

function something()
	local act = db.actor
	local vrtx = act:game_vertex_id()
	do something_else(act, vrtx)
end


(A2)

function something()
	local act = db.actor
	local vrtx = db.actor:game_vertex_id()
	do something_else(act, vrtx)
end


------------

And these?

(B1)

function r()
local t = {"friend", "enemy"}
	for k, v in pairs (t) do
		if db.actor == v then
			return
		end
	end
end


(B2)

function r()
	if db.actor == "friend" then
		return
	end
	if db.actor == "enemy" then
		return
	end
end


(We could also exploit the knowledge that "friend" and "enemy" are mutually exclusive to write:)

(B3)

function r()
	if db.actor == "friend" then
		return
	elseif db.actor == "enemy" then
		return
	end
end


(B4)

function r()
	if db.actor == "friend" then
		return
	else
		if db.actor == "enemy" then
			return
		end
	end
end


Which of these is fastest?
  01:23:28  29 January 2013
profilee-mailreply Message URLTo the Top
Daemonion
All About Audio
(Resident)

 

 
On forum: 09/27/2011
Messages: 567
What different in speed are we talking about here? A tenth of a second?
  02:19:58  29 January 2013
profilee-mailreply Message URLTo the Top
SetaKat
Ex modder, Zones only ferret and will someday release a game
(Resident)

 

 
On forum: 02/20/2010
Messages: 6340
Between B1 and B2, B2 is faster. The pairs() function is supposed to be quite slow.
Between A1 and A2, I'd imagine A1 is faster, since it doesn't need to look up the actor object a 2nd time.
B3 and B4, going by what I remember from C#, are exactly the same when compiled and excuted. I'd imagine it'll be the same for Lua when interpreted.
  02:35:30  29 January 2013
profilee-mailreply Message URLTo the Top
Alundaio
Sad Clown
(Resident)

 

 
On forum: 04/05/2010
 

Message edited by:
Alundaio
01/29/2013 3:09:09
Messages: 2230
pairs() is slow. Using a regular for loop with an indexed table is TWICE as fast when appropriate. There is a myth that ipairs is faster then pairs but they are about the same. I seen a few benchmarks with for loop v. pairs v. while v. ipairs and it showed for loop was slowest but that's a lie. I used to have a really good source for lua optimization that showed benchmarks for the most common functions and routines but I can't seem to find it.

As for B3 and B4 it's actually faster to do this in lua:


return val == "friend" or val == "enemy"



if-else:

if db.actor:relation(npc) == game_object.friend then
	return 1
elseif db.actor:relation(npc) == game_object.enemy then
	return 2
elseif db.actor:relation(npc) == game_object.neutral then
	return 3
end



short-hand is faster:

return db.actor:relation(npc) == game_object.friend and 1 or db.actor:relation(npc) == game_object.enemy and 2 or db.actor:relation(npc) == game_object.neutral and 3




It's barely noticeable when you use different methods unless you are doing thousands of calculations in a short time. The true key to lua optimization is actually localizing and scoping variables properly; it can be a dramatic difference.

But all that said, "Premature optimization is the root of all evil."
  10:35:35  29 January 2013
profilee-mailreply Message URLTo the Top
Decane
Senior Resident
 

 
On forum: 04/04/2007
 

Message edited by:
Decane
01/29/2013 10:56:06
Messages: 1701
I should not have written these in haste; I forgot to mention that in the case of B3 and B4, "friend" and "enemy" are the only possible values for the variable db.actor. So there is no "neutral" or anything else. However, if there were, then would B3 be faster? I suspect so because the "else" in B4 is doing the check, 'if not db.actor == "friend"', which seems to be equivalent to 'if db.actor == "enemy" or db.actor == "neutral"' with two other possibilities (???), so that the code in B4 is actually interpreted like this:

function r()
	if db.actor == "friend" then
		return
	elseif db.actor == "neutral" or db.actor == "enemy" then
		if db.actor == "enemy" then
			return
		end
	end
end

And of course, in this case, B4 would be slower since it is doing a redundant check. Is this correct?

--------------

Alundaio, thanks for those insights. GSC's code is filled to the brim with ipairs() ...

--------------

I have a few more questions. Which of these is faster, if either:

(A1)
function is_bandit_happy()
	local bandit_mood = sim_faction.get_mood("bandit")
	return (bandit_mood ~= "depressed")
	and (bandit_mood ~= "a bit blue")
	and (bandit_mood ~= "content")
end

(A2)
function is_bandit_happy()
	local bandit_mood = sim_faction.get_mood("bandit")
	return not (bandit_mood == "depressed")
	and not (bandit_mood == "a bit blue")
	and not (bandit_mood == "content")
end

Assume that our 'bandit mood table' does not contain a value for "happy". If I had to guess, I would assume that ("" ~= "") is shorthand for (not "" == ""), but in this case, lua would need to interpret the shorthand, whereas it would not need to do that with the reference notation. So in theory, (not "" == "") would be faster?

Also, can I do this in lua:


(A3)
function is_bandit_happy()
	local bandit_mood = sim_faction.get_mood("bandit")
	return bandit_mood ~= ("depressed" or "a bit blue" or "content")
end

If so, will this make the code any faster?

--------------

Finally, a question about localizing variables (again): is it faster to push local variables inside a function as much as possible (i.e. to make their scope as narrow as possible) or is it better to define them so that their scope is as wide as possible (within the function)? Example:


(B1)
function bandit_is_happy()
	local bandit_mood = sim_faction.get_mood("bandit")
	if bandit_mood == "happy" then
		local bandit_is_happy
		-- define and do something with variable bandit_is_happy
	end
end

vs.


(B2)
function bandit_is_happy()
	local bandit_mood = sim_faction.get_mood("bandit")
	local bandit_is_happy
	if bandit_mood == "happy" then
		-- define and do something with variable bandit_is_happy
	end
end

Thanks for all the replies, guys. This has been very fruitful so far.

EDIT: Removed smilies.
  13:59:01  29 January 2013
profilee-mailreply Message URLTo the Top
ThunderFreak
Senior Resident
 

 
On forum: 08/07/2009
 

Message edited by:
ThunderFreak
01/29/2013 20:55:44
Messages: 685
One hint to boost your code a little bit more.

NEVER declare a variable inside a for ... end block.
1. This variable is not valid outside the block. Also valid for if ... end as well.
2. As long you are looping thru for ... end evertime a variable declaration (local variable = ) is called a new variable will be created which ends up in indexed variables, because as long you are looping the variable is not deleted.

B2 is not really faster to B1 but the variable declaration is outside the if ... end block. This makes the variable valid inside the and outside the if ... end block.
  15:36:23  29 January 2013
profilee-mailreply Message URLTo the Top
Decane
Senior Resident
 

 
On forum: 04/04/2007
Messages: 1701
Good stuff!
 
Each word should be at least 3 characters long.
Search:    
Search conditions:    - spaces as AND    - spaces as OR   
 
Forum Index » S.T.A.L.K.E.R.: Shadow of Chernobyl Forum » Mod discussion
 

All short dates are in Month-Day-Year format.


 

Copyright © 1995-2020 GSC Game World. All rights reserved.
This site is best viewed in Internet Explorer 4.xx and up and Javascript enabled. Webmaster.
Opera Software products are not supported.
If any problem concerning the site functioning under Opera Software appears apply
to Opera Software technical support service.