Cуdigos Otimizados
#1

Sobre
Percebi ultimamente que sempre onde surgem discussхes para otimizaзхes de cуdigos em postagens aleatуrias, hб vбrias contribuiзхes e feedbacks, mas essas otimizaзхes sгo perdidas ali.

A partir disso, pensei em criar um tуpico onde se concentrem somente cуdigos relacionados a otimizaзгo e melhor desempenho, para podermos ter tudo isso localizado em somente um tуpico.

Alйm de servir como incentivo para novatos aprenderem melhores formas de como aplicar suas lуgicas, tambйm servirб como um mar de conhecimentos, pois todos sempre temos o que aprender com os demais.
Regras
1. Poste somente dicas relacionadas a otimizaзгo/desempenho de cуdigos, descrevendo qual o objetivo e dando exemplos de uso.
2. Sу responda postagens se for para corrigir dicas erradas ou contribuir com mais dicas da mesma natureza.
3. Tenha certeza de que sua dica conta com um fundamento teуrico e funcional na prбtica.
Reply
#2

@VOU DAR EDIT.
Reply
#3

GetPlayerPoolSize й melhor que MAX_PLAYERS ou feroach
Reply
#4

Quote:
Originally Posted by s4kuL
Посмотреть сообщение
GetPlayerPoolSize й melhor que MAX_PLAYERS ou feroach
Nгo sabe, nгo fala!
Foreach passa apenas pelos jogadores online, enquanto GetPlayerPoolSize pega o ID mais alto conectado, fazendo vocк passar por todos os ids atй ele e ainda por cima checando qual estб ou nгo online. Entгo, Foreach -> GetPlayerPoolSize -> MAX_PLAYERS й a ordem de custo de performance (do menor consumidor para o maior).
Reply
#5

Static

Quando possнvel, sempre dк preferкncia a static, alйm de ser mais rбpida que new, tem mъltiplas vantagens.

Aqui aponto 3 tipos de usos:
PHP код:
/*
    > Em includes
    Ao declarar uma variбvel estбtica dentro de uma include, ela sу й acessнvel dentro da mesma, e
    nгo й possнvel manipulб-la em qualquer outro arquivo que importar essa mesma include. Isso
    evita que surjam problemas com nomenclatura de variбveis jб definidas.
*/
//include my_var.inc
static myVar;
myVar 13;
//gamemode
#include <my_var>
main()
{
    
printf("%d"myVar);//erro, variбvel myVar nгo definida

PHP код:
/*
    > Cуdigos de repetiзгo
    Cуdigos que sгo chamados repetidamente й um excelente caso para se usar static. Por nгo ser
    destruнda, a static economiza muito processamento, uma vez que nгo precisa ser definida novamente
    toda vez que o cуdigo for executado.
*/
public OnPlayerUpdate(playerid)
{
    static 
timeExecuted;
    if(
timeExecuted != 0)
        
printf("OnPlayerUpdate executada em %dms"GetTickCount() - timeExecuted);
    
timeExecuted GetTickCount();
    return 
1;
}
/*
    > OBS: Exatamente por nгo ser destruнda que deve-se ficar atento ao seu uso, pois caso vocк queira,
    por exemplo, criar uma variбvel para armazenar valores diferentes para cada jogador onde precisarб
    trabalhar com esses valores, deve levar em conta que a variбvel estбtica ficarб com o ъltimo valor
    setado, e isso farб com que vocк perca o valor setado para outros jogadores e ficarб, claro, o valor
    modificado por ъltimo. Como soluзгo, seria necessбrio indexar a variбvel estбtica, do contrбrio esse
    conflito й inevitбvel.
    Isso se deve ao fato de que N jogadores estarгo partilhando da mesma variбvel, e no fim da execuзгo
    do processo de um jogador, o prуximo processo de outro terб o valor que o jogador anterior alterou.
*/
public OnPlayerUpdate(playerid)
{
    static 
Float:playerPos[3];
    
printf("A ъltima posiзгo de %d й %.3f, %.3f, %.3f"playeridplayerPos[0], playerPos[1], playerPos[2]);
    
GetPlayerPos(playeridplayerPos[0], playerPos[1], playerPos[2]);
    
printf("A nova posiзгo de %d й %.3f, %.3f, %.3f"playeridplayerPos[0], playerPos[1], playerPos[2]);
    
/*
        Nesse caso, somente o segundo print contarб com a informaзгo verdadeira, pois se houver mais que
        um jogador no servidor, os valores de playerPos serгo de outros jogadores.
    */
    
return 1;
}
//Correto seria:
public OnPlayerUpdate(playerid)
{
    static 
Float:playerPos[MAX_PLAYERS][3];
    
printf("A ъltima posiзгo de %d й %.3f, %.3f, %.3f"playeridplayerPos[playerid][0], playerPos[playerid][1], playerPos[playerid][2]);
    
GetPlayerPos(playeridplayerPos[playerid][0], playerPos[playerid][1], playerPos[playerid][2]);
    
printf("A nova posiзгo de %d й %.3f, %.3f, %.3f"playeridplayerPos[playerid][0], playerPos[playerid][1], playerPos[playerid][2]);
    
/*
        Sem risco de ocorrer interferкncias, pois playerPos estб indexada com o id dos jogadores.
    */
    
return 1;

PHP код:
/*
    > Em funзхes
    Assim como declarar variбveis estбticas sу permitem o acesso e manipulaзгo da mesma dentro do arquivo
    em que ela foi declarada, as funзхes partem do mesmo comportamento. Se vocк criar uma funзгo estбtica
    dentro de uma include, essa funзгo nгo poderб ser chamada por outro arquivo que carregar tal include.
*/
//include my_func.inc
static GetUserName(playerid)
{
    static 
playerName[MAX_PLAYERS];
    return ((
GetPlayerName(playeridplayerNameMAX_PLAYERS)), playerName);
}
//gamemode
#include <my_func>
public OnPlayerConnect(playerid)
{
    
printf("%s conectou-se."GetUserName(playerid));//erro, funзгo GetUserName nгo definida

Reply
#6

Quote:
Originally Posted by renatog
Посмотреть сообщение
Nгo sabe, nгo fala!
Foreach passa apenas pelos jogadores online, enquanto GetPlayerPoolSize pega o ID mais alto conectado, fazendo vocк passar por todos os ids atй ele e ainda por cima checando qual estб ou nгo online. Entгo, Foreach -> GetPlayerPoolSize -> MAX_PLAYERS й a ordem de custo de performance (do menor consumidor para o maior).
Acho que vou fazer um tutorial pra tu ...
Reply
#7

@Bruno, tem como vocк provar esse seu exemplo da static na OnPlayerUpdate? Sinceramente acho que vocк estб completamente equivocado, pois o servidor nгo vai executar a OnPlayerUpdate do jogador ID 1 se a do ID 0 estiver sendo executada, tornando impossнvel esse conflito.
Dizer que 'static' й mais rбpida que 'new' й mais um equнvoco seu, vocк nem se deu ao trabalho de dizer o motivo disso ou falar sobre a diferenзa das duas no stack.

As variбveis locais (dentro de funзхes ou callbacks) criadas com a keyword 'new' sу existem enquanto seu bloco й executado (sгo criadas quando a funзгo й chamada e destruнdas quando a funзгo termina de ser executada).

A keyword 'static', por outro lado, define uma variбvel que permanecerб na memуria, ou seja, serб criada apenas uma vez e existirб atй o servidor ser reiniciado/desligado. A vantagem й usб-la em funзхes ou callbacks que se repetem muito, pois nгo precisarб ser criada e destruнda toda vez que seu bloco for executado, por isso que vocк deve ter cuidado com ela porque, assim como a sua existкncia, seu valor permanece o mesmo da ъltima vez que foi utilizada.
Entгo, se vocк nгo estiver escrevendo uma funзгo/callback que й chamda vбrias e vбrias vezes constantemente, usar 'static' nгo se torna tгo necessбrio, pois o que vocк ganha de performance vocк "perde" de memуria (afinal a variбvel nгo vai liberar a memуria que ela ocupada).

Em nнvel global, as variбveis 'static' sу nгo permitem que outros arquivos tenham conhecimento de sua existкncia, do modo que o Bruno demonstrou (уtimo para includes).

@s4kul, pode fazer o tutorial dizendo como for loops com GetPlayerPoolSize sгo melhores que foreach player kk.
Reply
#8

Quote:
Originally Posted by renatog
Посмотреть сообщение
@Bruno, tem como vocк provar esse seu exemplo da static na OnPlayerUpdate? Sinceramente acho que vocк estб completamente equivocado, pois o servidor nгo vai executar a OnPlayerUpdate do jogador ID 1 se a do ID 0 estiver sendo executada, tornando impossнvel esse conflito.
Vocк estб certo, no meu exemplo eu realmente me equivoquei, o conflito que estava me referindo й pelo fato da static continuar com o mesmo valor que foi armazenado por ъltimo, o que й um problema para cуdigos que queiram usar do valor antigo armazenado e esse sendo diferente para cada jogador.

O conflito que dei exemplo jamais poderia ocorrer, pois SA-MP й single-thread, o qual sу trata uma requisiзгo de processamento por vez.

Onde poderia ocorrer um "conflito", seria em cуdigos como do exemplo abaixo, sendo testados com 2 jogadores, id 0 e 1:
PHP код:
public OnPlayerUpdate(playerid)
{
    
/*
        Aqui temos um "conflito" que ocorre, onde a variбvel estбtica myVar й usada por OnPlayerUpdate do
        jogador id 0 e 1. Ambos manipulam a mesma variбvel, logo, quando um processamento de OnPlayerUpdate
        terminar, o ъltimo valor armazenado em myVar serб o mesmo no prуximo processamento de OnPlayerUpdate.
        Como resultado, teremos variaзхes entre "<!> Nгo й mъltimo de 2/5" e "Й mъltiplo de 2/5" para ambos
        jogadores.
    */
    
static myVar;
    if(!
playerid)
    {
        
myVar += 2;
        if(!(
myVar 2))
            
SendClientMessage(playerid, -1"Й mъltiplo de 2");
        else
            
SendClientMessage(playerid, -1"<!> Nгo й mъltimo de 2");
    }
    else
    {
        
myVar += 5;
        if(!(
myVar 5))
            
SendClientMessage(playerid, -1"Й mъltiplo de 5");
        else
            
SendClientMessage(playerid, -1"<!> Nгo й mъltimo de 5");
    }
    
    return 
1;

Quote:
Originally Posted by renatog
Посмотреть сообщение
Dizer que 'static' й mais rбpida que 'new' й mais um equнvoco seu, vocк nem se deu ao trabalho de dizer o motivo disso ou falar sobre a diferenзa das duas no stack.
Afirmei isso em base de que static nгo necessita alocar memуria novamente ao ser executada em um cуdigo repetitivo, o que faz ganhar em velocidade de new.

Obrigado pelas contribuiзхes!
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)