Kolejne skrócenie pętli (for) graczy?
Ossal
21.02.2015
"Kolejne" w temacie odnosi się do tego, że zamiast robić for(new i=1;i<33;i++) robi się for(i=1;i<MaxPlayers;i++) gdzie MaxPlayers to zmienna globalna z przypisanym get_maxplayers() w plugin_init <== choć nie wiem po co to piszę, bo chyba każdy to wie
Mój pomysł to coś takiego:
for(i=1;i<=MaxPlayers;i++){ if(!is_user_connected(i)) break //nasz warunek lub nic //kod wykonany na graczu }A pytanie do was jest proste: czy jest pewność że w 100% sytuacji taka pętla zadziała poprawnie?
No i oczywiście czy jest sens coś takiego robić, nawet przy pętlach wykonywanych co chwila zaoszczędzenie będzie niewielkie, ale biorąc pod uwagę serwer 32 sloty i grający obecnie np 6 osób, to wydawać by się mogło, że coś tam jednak oszczędzimy.
Z góry dzięki za odpowiedź
Użytkownik radim edytował ten post 21.02.2015 21:03
Rivit
21.02.2015
Gracze w cs są indexowani od 1 do 32, jak jest powiedzmy 5 graczy na serwie i wyjdzie ten z indexem 3 to gracze 4 i 5 zostają "zdegradowani" do indexu o jeden mniejszego (po czym następuje magiczne przerzucenie wszystkich danych w każdym pluginie na nowe indexy, sam na wiem jak to się dzieję )
Wydaje mi się że indexy nie "podsuwają się".
for(i=1;i<MaxPlayers;i++)
Na:
for(i=1;i<=MaxPlayers;i++)
Widzę, że Ty też wszędzie doszukujesz się oszczędności, mój człowiek
GwynBleidD
21.02.2015
Ossal
21.02.2015
co do <= to oczywiście niedopatrzenie, takich błędów raczej nie robię
Jesteś pewien że indexy są stałe, a nowi gracze wskakują na miejsce rozłączonych?
Jak to, magia nie istnieje?
Użytkownik Ossal edytował ten post 21.02.2015 20:45
Ossal
22.02.2015
Dobra tamto było lekkomyślne troszkę. Zmieniamy taktykę:
#include <amxmodx> new MaxPlayers=0 public plugin_init(){ register_plugin("Nazwa Pluginu", "1.0", "Ossal") } public client_connect(id){ if(id>MaxPlayers) MaxPlayers=id } public client_putinserver(id){ if(id!=MaxPlayers) return do{ MaxPlayers-- } while(!is_user_connected(MaxPlayers)) }
Wówczas pętla będzie wyglądać tak samo jak standardowa [for(new i=1;i<=MaxPlayers;i++)], ale zmienna przechowująca get_maxplayers() będzie przechowywać inną liczbę (przy małej ilości graczy względem ilości slotów nawet sporo mniejszą)
Co powiecie na coś takiego? Nie sknociłem czegoś? Może mi ktoś powiedzieć czy coś takiego zaoszczędzi trochę zasobów? Przy jednej pętli graczy na rundę może nie specjalnie będzie widać różnicę, ale z perspektywy całej mapy lub przy wykonywaniu pętli np przy każdej śmierci może już bardziej? Dzięki za odpowiedzi
PS jeżeli gracze dostają index przed putinserver to proszę o poprawkę
Użytkownik Ossal edytował ten post 22.02.2015 13:10
Ossal
22.02.2015
Boshe, co ja napisałem Oczywiście że gracz dostaje index wcześniej, dostaje go w pierwszej funkcji wywołanej gdy wchodzi na serwer czyli prawdopodobnie client_connecting(), sprawdzę potem, która jest pierwsza na pewno client_putinsever jest ostatnią funkcją tego typu
//Proszę o dorzucenie powyższego do posta powyżej, a ten post do usunięcia
GwynBleidD
22.02.2015
for (new id=1; id<=maxplayers; ++id) { if (!client_connected(id)) continue; // jakiś dłużej wykonujący się kod }to próba skrócenia tej pętli w jakikolwiek sposób skróci czas jej wykonywania o 0.5% może troszkę więcej, bo przecież i tak kod wewnątrz pętli się dla nieistniejących graczy nie wykona, a sprawdzenie czy gracz jest połączony i pominięcie danej iteracji pętli gdy nie jest zajmuje ułamek sekundy...
Jeśli z jakiegoś powodu chcesz, by pętla wykonała się dokładnie tyle razy, ile masz graczy użyj:
new Players[32], Num, i; get_players(Players, Num); for(i=0; i < Num; i++) { new id=Players[i]; // jakiś dalszy kod }ale ma to sens gdy z jakiegoś naprawdę konkretnego powodu chcesz by pętla nie wykonała się ani razu więcej, np licznik i z pętli wykorzystujesz gdzieś dalej do określenia ile razy pętla się wykonała (np gdy szukasz tą pętlą gracza konkretnego i na nim zatrzymujesz pętlę a następnie chcesz określić z jakiegoś powodu który z kolei był to gracz).
dużo ważniejsze jest optymalizowanie wywołań długiego kodu w eventach takich jak prethink, add to fullpack, niwelowanie wykonujących się co chwilę tasków, niwelowanie kodu który wstrzymuje serwer na dłuższą chwilę (bo np zawiera pętlę która wykonuje się 10000 razy). Warto użyć do tego typu optymalizacji profilera: https://forums.allie...00&postcount=87ale pamiętaj, że nie nadaje się on na działające serwery, jedynie do szukania problemów i rzeczy do zoptymalizowania.