30.09.2010, 07:34
GetMaxPlayers is a unused, maybe even forgotten function. Instead of it, we use the good old MAX_PLAYERS. MAX_PLAYERS, who after the release of 0.3, has been defined as 500. Because 500 is the max ammount of players a server can have. MAX_PLAYERS is most found in variables and loops. And it's a well known fact amongst experienced SA-MP scripters, that these 2 elements is very good at eating server CPU. Therefor we do with all our might tell the new people, that they need to be careful. Like we often tell them, that strings shouldn't be 256. But when we give them help, and show them some code. We give them a loop that could look like this:
Anyone who has worked with loops, can tell that this will go from 0 to 1 to 2 to 3 and all the way up to 499. 0 to 499 is a long and not a very suffecient way to go. It will simply eat your CPU.
Now let's go back to the fact, that we tell players NOT to use a 256 cells strings, because it's very bad for your server performance. Take a script, and say that the guy who made it have learned not to use 256 cells strings. He optimizes hes server, and feels happy about it. He just cut half of all hes 40 strings. This saved him an amazing count of 20480 bytes! According to my small calculation of 128(cells saved)*40(strings)*4(bytes). new something[MAX_PLAYERS] works the same way, as a string. exept we use the cells diffrently. Instead of saving a letter on each we save a number on each. The happy guy, who just saved 20480 bytes. Is the owner of a small popular server with 40 players. Let's say he haves 50 global variables, using MAX_PLAYERS. This gives a byte use of 100000 bytes. Where he only needs 8000 of them. The rest of the many bytes, is wasted. I hope you get the idea of that using MAX_PLAYERS will (in almost any cases) be WAY to many. Most big servers only haves 100 slots! Therefor making MAX_PLAYERS(500) into 100 will spare you from wasting 80% CPU! But instead of changing all your variables, everytime your server changes ammount of slots, or releasing insufficient code to the public. Simply because it's impossible to tell how many slots their server uses. Use GetMaxPlayers()! If you read on the wiki https://sampwiki.blast.hk/wiki/GetMaxPlayers . You will know that this function opens the .CFG file and reads how many slots the server is on. This can save you a bunch of bytes! And it works the same way as MAX_PLAYERS.
Heres some examples with a 40 slots server:
This small code uses 6000, 5520 bytes more than needed, just on variables.
And the loop will go through 460 unneccesary IDs. Since PAWN is a single threaded language, it will first go through ALL the 500 numbers, before it begins on anything else. This can result in information for other players comes late. This is known as lag.
Here is a more efficient piece of code which does the same
This script only uses 480 bytes on variables for the 40 players server. And the loop will be finished 92% faster!
And notice how similar the 2 pieces of code really is, you don't need to learn alot of new stuff on it.
And im not 100% sure on this 1 but i think it might be a bit unefficient to open the .CFG file every time. So therefor you can just make a variable like this under Main(): new Max_Players = GetMaxPlayers();
This will use 4 bytes, but will save you from using time opening the file every time.
So therefor i come to conclusion that GetMaxPlayers() > MAX_PLAYERS in any case exept, if you actualy run a server with 500 slots.
Any feedback is welcome
Edit: Also forgot to mention that even though GetMaxPlayers() will help optimize your loops, foreach by ****** will still be the best choice for looping
pawn Код:
for(new i=0; i<MAX_PLAYERS; i++)
{
if(IsPlayerConnected(i))
{
Now let's go back to the fact, that we tell players NOT to use a 256 cells strings, because it's very bad for your server performance. Take a script, and say that the guy who made it have learned not to use 256 cells strings. He optimizes hes server, and feels happy about it. He just cut half of all hes 40 strings. This saved him an amazing count of 20480 bytes! According to my small calculation of 128(cells saved)*40(strings)*4(bytes). new something[MAX_PLAYERS] works the same way, as a string. exept we use the cells diffrently. Instead of saving a letter on each we save a number on each. The happy guy, who just saved 20480 bytes. Is the owner of a small popular server with 40 players. Let's say he haves 50 global variables, using MAX_PLAYERS. This gives a byte use of 100000 bytes. Where he only needs 8000 of them. The rest of the many bytes, is wasted. I hope you get the idea of that using MAX_PLAYERS will (in almost any cases) be WAY to many. Most big servers only haves 100 slots! Therefor making MAX_PLAYERS(500) into 100 will spare you from wasting 80% CPU! But instead of changing all your variables, everytime your server changes ammount of slots, or releasing insufficient code to the public. Simply because it's impossible to tell how many slots their server uses. Use GetMaxPlayers()! If you read on the wiki https://sampwiki.blast.hk/wiki/GetMaxPlayers . You will know that this function opens the .CFG file and reads how many slots the server is on. This can save you a bunch of bytes! And it works the same way as MAX_PLAYERS.
Heres some examples with a 40 slots server:
pawn Код:
new Money[MAX_PLAYERS];
new Score[MAX_PLAYERS];
new Team[MAX_PLAYERS];
for(new i=0; i<MAX_PLAYERS; i++)
{
Score[i] = GetPlayerScore(playerid);
Money[i] = GetPlayerMoney(playerid);
Team[i] = GetPlayerTeam(playerid);
return 1;
}
And the loop will go through 460 unneccesary IDs. Since PAWN is a single threaded language, it will first go through ALL the 500 numbers, before it begins on anything else. This can result in information for other players comes late. This is known as lag.
Here is a more efficient piece of code which does the same
pawn Код:
new Money[GetMaxPlayers()];
new Score[GetMaxPlayers()];
new Team[GetMaxPlayers()];
for(new i=0; i<GetMaxPlayers; i++)
{
Score[i] = GetPlayerScore(playerid);
Money[i] = GetPlayerMoney(playerid);
Team[i] = GetPlayerTeam(playerid);()
return 1;
}
And notice how similar the 2 pieces of code really is, you don't need to learn alot of new stuff on it.
And im not 100% sure on this 1 but i think it might be a bit unefficient to open the .CFG file every time. So therefor you can just make a variable like this under Main(): new Max_Players = GetMaxPlayers();
This will use 4 bytes, but will save you from using time opening the file every time.
So therefor i come to conclusion that GetMaxPlayers() > MAX_PLAYERS in any case exept, if you actualy run a server with 500 slots.
Any feedback is welcome
Edit: Also forgot to mention that even though GetMaxPlayers() will help optimize your loops, foreach by ****** will still be the best choice for looping