Durchgeht er ja jedes mal das Server Limit von 500 Usern. Wie geht es perfomanter?
Am besten wäre es einfach, sowas zu machen, das würde beide deiner Probleme auf einen Schlag lösen:
#undef MAX_PLAYERS
#define MAX_PLAYERS 25
Dann würdest du eben nur 25 Einträge durchgehen hahaha 
Aber schon richtig foreach wäre am besten:
http://forum.sa-mp.com/showthread.php?t=570868
Gehen würde auch sowas wie:
for(new i=GetPlayerPoolSize(); i!=-1; i--)
Das beispielsweise beginnt ab der höchsten spielerid auf dem Server und nicht z.B. ab 500 
Also zur Verdeutlichung:
MAX_PLAYERS = Ein fester (konstanter) Wert, den du für Arrays nutzen kannst. (Da dort nur feste Werte verwendet werden können, also Dinge die sich nicht ändern. Die müssen von vorne herein fest definiert sein.) Habe oben ja gezeigt, wie du das anpassen kannst.
GetMaxPlayers = Diese Funktion liest dir aus der server.cfg den Wert aus. Ist schlecht und kann nicht für Arrays verwendet werden, da es eine Funktion ist und keine konstante! Also am Besten einfach MAX_PLAYERS den Wert von der server.cfg mittels dem Makro trick oben anpassen.
GetPlayerPoolSize = Gibt die höchste Spielerid auf dem Server wieder. Halt gut geeignet für Loops, aber foreach ist besser, da bei foreach keine Lücken zwischen den IDs entstehen. Quasi wenn ID 4 die höchste Spielerid ist, aber nur ID 1 noch online. Dann beginnt die Loop trotzdem von 4 runter zu zählen. Und bei foreach hättest du nur 2 anstatt 5 (4-0) Einträge.
Zu deinem 2. Punkt kann man nicht viel sagen.
Es gibt Memory Editing Plugins, so dass man Variablen dynamisch allozieren kann.
Einfacher wäre der spezielle Gebrauch von PVars, da du diesen Speicher wieder freigeben kannst.
Oder eben gezielte Anpassung des Makros von MAX_PLAYERS 