Introduction
PRISM is pretty fast, but there are some common assumptions about scripts:
Note that many of these optimizations should be taken in context. An admin command probably doesn't need fine-tuned optimizations. But a timer that executes every 0.1 seconds, or a MCI / NLP packet hook, should definitely be as fast as possible.
Always Save Results
Observe the example code snippet below:
This is a mild example of "cache your results". When the compiler generates assembly for this code, it will (in pseudo code) generate:
Now, the compiler will only generate this:
If getClientByUCID were a more expensive operation (it's relatively cheap), we would have recalculated the entire result each branch of the if case, wasting CPU cycles.
Similarly, this type of code is usually not a good idea:
Better code is:
I can't stress this point enough, it can be devatating to the performance of your script, the former getting up to and over 600 times SLOWER in the better example.
Similarly, you may not want to put $this->getMaxClients() in a loop about players. While it is a very cheap function call, it can become significant in highly performance-sensitive code.
Switch instead of If
If you can, you should use switch cases instead of if. This is because for an if statement, the compiler must branch to each consecutive if case. Using the example from above, observe the switch version:
This will generate what's called a "case table". Rather than worm through displaced if tests, the compiler generates a table of possible values. The best case is:
If your switch cases are listed in perfectly sequential order (that is, skipping no numbers, either ascending or descending), the PHP engine can make the best optimizations. For example, "7,8,9" and "2,1,0" are examples of perfect switch cases. "1,3,4" is not.
Foreach instead of For
You should use foreach when you are doing a simple iterating over an array.
While instead of Foreach
You should use while instead of foreach when you intend to modifty data within the iterating array.
No code is good code
With any programming language, the less code you can write the better. If you can find a single function that would of done what you did with five function calls use that one function.
Conclusion
Although optimization is important, you should always keep context in mind. Don't replace every single foreach in your plugins with while just because it might be faster. Identify the areas of your plugin where optimization is significant, and tweak from there.
PRISM is pretty fast, but there are some common assumptions about scripts:
- You can't possibly make it any faster.
- It's interpreted, so it's always going to be slow.
- Details don't matter, as it's only "scripting" anyway.
Note that many of these optimizations should be taken in context. An admin command probably doesn't need fine-tuned optimizations. But a timer that executes every 0.1 seconds, or a MCI / NLP packet hook, should definitely be as fast as possible.
Always Save Results
Observe the example code snippet below:
<?php
if ($this->getClientByUCID($UCID)->UName == 'Scawen')
{
# Code
}
else if ($this->getClientByUCID($UCID)->UName == 'Victor')
{
# Code
}
else if ($this->getClientByUCID($UCID)->UName == 'Eric')
{
# Code
}
?>
CALL getClientByUCID
COMPARE+JUMP
CALL getClientByUCID
COMPARE+JUMP
CALL getClientUCID
COMPARE+JUMP
<?php
$UName = $this->getClientByUCID($UCID)->UName;
if ($UName == 'Scawen')
{
# Code
}
else if ($UName == 'Victor')
{
# Code
}
else if ($UName == 'Eric')
{
# Code
}
?>
CALL getClientByUCID
COMPARE+JUMP
COMPARE+JUMP
COMPARE+JUMP
If getClientByUCID were a more expensive operation (it's relatively cheap), we would have recalculated the entire result each branch of the if case, wasting CPU cycles.
Similarly, this type of code is usually not a good idea:
<?php
for ($i = 0; $i < strlen($string); $i++)
?>
<?php
for ($i = 0, $len = strlen($string); $i < $len; ++$i)
?>
Similarly, you may not want to put $this->getMaxClients() in a loop about players. While it is a very cheap function call, it can become significant in highly performance-sensitive code.
Switch instead of If
If you can, you should use switch cases instead of if. This is because for an if statement, the compiler must branch to each consecutive if case. Using the example from above, observe the switch version:
<?php
$UName = $this->getClientByUCID($UCID)->UName
switch ($UName)
{
case 'Scawen':
# Code
break;
case 'Victor':
# Code
break;
case 'Eric':
# Code
break;
}
?>
JUMP Table[CALL $this->getClientByUCID($UCID)->UName]
If your switch cases are listed in perfectly sequential order (that is, skipping no numbers, either ascending or descending), the PHP engine can make the best optimizations. For example, "7,8,9" and "2,1,0" are examples of perfect switch cases. "1,3,4" is not.
Foreach instead of For
You should use foreach when you are doing a simple iterating over an array.
While instead of Foreach
You should use while instead of foreach when you intend to modifty data within the iterating array.
No code is good code
With any programming language, the less code you can write the better. If you can find a single function that would of done what you did with five function calls use that one function.
Conclusion
Although optimization is important, you should always keep context in mind. Don't replace every single foreach in your plugins with while just because it might be faster. Identify the areas of your plugin where optimization is significant, and tweak from there.
Source Work: Optimizing Plugins (SourceMod Scripting) - Copyleft: GNU FDL Version 1.2, November 2002
Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.