Code Optimization Rules Of Thumb
So, in the work I've been doing with Oasis recently, especially optimizing and getting it cleaned up for open-source use, I keep noticing little themes and rules of thumb pop up repeatedly. This especially holds true for making the different modules modular and easy to update later on, but have also included things to just make building simple functions easier as I go.
Things like:
If you find yourself using the same block of code across multiple functions, write a function for it.
If you're going to refer to a global (especially namespaced) variable more than once in a function, load it into a local variable.
Save useful code that other people wrote.
--
What are some coding rules of thumb you've found? (Admin included!)
the way she tells me I'm hers and she is mine
open hand or closed fist would be fine
blood as rare and sweet as cherry wine
0
Comments
function should_i_rewrite_this(block) { local creation_year, written_by; if !valid_function(block) and !valid_subroutine(block) then { return; } creation_date = get_year_code_was_written(block); written_by = get_code_creator(block); if written_by = search_persona("ivoln") then { return 1; } else if creation_year >= 2011 and (written_by = search_persona("razmael") or written_by = search_persona("oleis")) then { return 0; } else if creation_year >= 2007 then { (* All old code can just go die *) return 1; } else if creation_year < 2007 then { return "YEAH BETTER NOT"; } return 0; }
Produces an error if returning a string, which is a totally accurate representation of old code.
Make sure all code is properly spaced to make it more easily read.
In the event of an error, drop a bunch of echo's and such between code blocks to see where things are going wrong.
Also, system building things I just remembered that have been stewing in my brain:
Build modules or distinct sections of code for a specific purpose. Example: Character database module (core functions, aliases, triggers), defense scripts, curing scripts.
Avoid using string comparisons with specific game data for code - use data entries that can be easily found and rewritten instead.
Have every module or distinct section of code be as self-reliant as possible, and if at all possible, only called up in ONE other place.
Avoid namespace poison - keep all of your core global tables in one central location and one standardized location across all modules.
If a function can't or shouldn't perform its specific function, have it return nil early in the script.
For Mudlet, avoid using Events as much as possible. Great idea, but super process-heavy. Not even necessary for open-source systems, except for things like sysOnLoad and sysDownloadEvent.
Also, 3,423,562,174x on @Toz's comment: superior logic implemented trumps superior code 100% of the time.
the way she tells me I'm hers and she is mine
open hand or closed fist would be fine
blood as rare and sweet as cherry wine
vensToAffs = {
curare = "paralysis",
aconite = "stupidity",
}
And sometimes, you want to know the reverse, i.e. what venom to use to deliver paralysis, then instead of looping through the table every single time you ever want to envenom, just loop through it once at startup and create the reverse table.
affsToVens = {}
for ven,aff in pairs(vensToAffs) do
affsToVens[aff] = ven
end
Take the time to create the right tables for the information you need, and a huge part of your processing becomes simple table lookups.
One:
function focus()
return o.bals.focus
and not tmp.paused
and not (affs.current.impatience
and not affs.attempted.impatience)
and not affs.current.stun
and not (affs.current.asleep
and not affs.attempted.asleep)
and not affs.current.unconscious
end
Two:
function focus()
return o.bals.focus
and not (tmp.paused
or (affs.current.impatience
and not affs.attempted.impatience)
or affs.current.stun
or (affs.current.asleep
and not affs.attempted.asleep)
or affs.current.unconscious)
end
One of these items causes Focus to spam off-balance on every prompt. The other doesn't (hopefully, reproducing the scenario is hard).
the way she tells me I'm hers and she is mine
open hand or closed fist would be fine
blood as rare and sweet as cherry wine
the way she tells me I'm hers and she is mine
open hand or closed fist would be fine
blood as rare and sweet as cherry wine
(On that note, I'm going on vacation )
Have a good vacation!
my thread was oleis' last post before he left on vacation squeeeee
the way she tells me I'm hers and she is mine
open hand or closed fist would be fine
blood as rare and sweet as cherry wine
Local variables are external when they're declared inside of a function, so to make your code even quicker, try to declare your locals outside of function calls.
function something()
local taffs = pvp.affs
local a_esult = false
for aff,pres in pairs(taffs) do
something
end
return a_result
end
That would be 2 external locals in that function, according to your explanation. What would be an internal one?
function something()
for aff, pres in pairs(taffs) do ...
end
If that's the case, why does anyone ever use anything but locals? What's the advantage of a global variable? Why wouldn't I just do:
local pvp = {}
and then just treat pvp like it's a global variable, but with the speed advantages of a local?
edit:
What I mean to ask is, if a system (say tripwire for the sake of argument) used these global namespaces:
tw = {}
pvp = {}
Could I speed up the entire system just by going to the very beginning, where pvp and tw are declared, and change them to:
local tw = {}
local pvp = {}
?