Note: The below comments are misguided and should be ignored. They remain for historical purposes only.
I have noticed quite a lot around here, including on the official wiki, significant overuse of array sizing functions to accommodate the array length parameters in many of SourceMod's functions. Of particular concern is how these functions are being used to measure strings and arrays of fixed length as defined during compilation. The sizeof() function must be executed every time it is called, and on a fixed length array it's
always going to come up with the same number.
Instead of using this practice, define the array using the #define feature then use the parameter name throughout your code. This allows you to easily change the array length with confidence that the change will propagate through your code. Remember that #define parameters are interpreted by the compiler and are incorporated into the compiled program as though the value were just typed in everywhere.
Here is an example which I pulled straight from the Menu API article on the wiki:
Code:
if (action == MenuAction_Select)
{
new String:info[32]
new bool:found = GetMenuItem(menu, param2, info, sizeof(info))
PrintToConsole(param1, "You selected item: %d (found? %d info: %s)", param2, found, info)
}
This would be better as follows:
Code:
if (action == MenuAction_Select)
{
#define info_length 32
new String:info[info_length]
new bool:found = GetMenuItem(menu, param2, info, info_length)
PrintToConsole(param1, "You selected item: %d (found? %d info: %s)", param2, found, info)
}
This will execute in exactly the same way but will run faster. Obviously the performance impact from something like the above is minimal but in other scenarios it can be pretty significant - plus, every little bit helps!
FYI - though I am not 100% certain on this - #define parameters don't have scope but they are read in order from top to bottom while compiling. They have to appear before the parameter name is used in code but where they are in scope is not a factor. The parameter info_length would remain defined for code outside of the if statement and even for subsequent functions - I THINK! However, they can also be re-defined later in the code, though you'll get a compiler warning.
There are many other scenarios where CPU time can be saved by using #define statements or other similar practices instead of using functions like sizeof() all the time. Consider a for loop, where you just have to have the code determine the array length for a good reason.
Many people would code it like this:
Code:
// Array example[] of unknown length was created earlier
for(new i = 0; i < sizeof(example); i++) {
example[i] *= 2; // Arbitrary in-loop code
}
In this loop, the sizeof() function is called many times - once for each loop. The following optimization is much faster:
Code:
// Array example[] of unknown length was created earlier
example_length = sizeof(example)
for(new i = 0; i < example_length; i++) {
example[i] *= 2; // Arbitrary in-loop code
}
Remember, fewer lines of code does not necessarily mean
faster code!
Anyway, this practice seems rampant so I wanted to comment on it.