SSGamers - 12 Anos online por você.

#SSGamers - A Comunidade que mais crescer no brasil!

Participe do fórum, é rápido e fácil

SSGamers - 12 Anos online por você.

#SSGamers - A Comunidade que mais crescer no brasil!

SSGamers - 12 Anos online por você.

Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.
Chegou o novo tema 6.5.5 - SSGamers - Servidores online de qualidade - Aproveite e entre para nossa comunidade, inscreva-se já! - Ouça nossa web radio - Veja nossas novidades - Participe dos nossos setores de jogos online - Parcerias aberta fale já com um administrador.

    Economia de memória para grandes Strings

    Weslley_Script
    Weslley_Script
    SS - Fundador
    SS - Fundador


    Steam Steam : WeslleySSGames
    Zello : WeslleySSGames
    Mensagens : 11381
    Moedas : 1031992
    Data de inscrição : 06/10/2011
    Idade : 28
    Localização : Brasil

    Economia de memória para grandes Strings Empty Economia de memória para grandes Strings

    Mensagem por Weslley_Script Qui 26 Ago 2021 - 17:51

    Este é um tutorial simples e rápido para você compreender algumas coisas básicas sobre declaração de vars/arrays em Pawn (1) e como economizar memória com isso (2).

    Vou passar rápido no tópico 1 (declaração de vars/arrays em Pawn) e me estender no tópico 2.
    Coisas que você precisa saber para entender este tópico:

    - Basicamente, todas as variáveis declaradas em Pawn (seja new, seja static) alocarão 32 bits (4 bytes ou 4B) p/cell.
    - Cells são representadas por colchetes var[0] e bytes por chaves var{0}.
    - Todo caractere da table ASCII (inclusive os especiais) compreendem nos decimais que vão de 0 a 255
    - 8 bits podem armazenar um número de 0 a 255.

    Logo podemos concluir que: 8 bits (1B) são suficientes para armazenar qualquer caractere (inclusive os especiais).
    Sendo assim, a maneira mais eficiente de armazenar uma mensagem dentro de uma string não é inserindo um caractere por cell (4B), e sim um caractere por byte, ou seja, 4 caracteres por cell.



    Como faremos isso?

    Fácil, use ' ! ' antes de declarar uma String.

    Ao invés de:
    Código PHP:
    Código:
    new String[16] = "Tutorial Maroto"; 

    Use:
    Código PHP:
    Código:
    new String[4] = !"Tutorial Maroto"; 

    Isso faz com que você economize 12 Bytes de um total de 16 (75%). Imagine fazer isso para um servidor inteiro, a memória cai muito.
    Enfim, tudo tem seus prós e contras. O nome desse tipo de string, de acordo com Pawn, é packed strings (mensagens compactadas), em que, realmente, alocam uma quantia menor de memória, mas não é possível que você use a função 'format' com elas, o que ferra tudo, porque são muito poucas as strings em um servidor que não passem por um format.vou mostrar uma alternativa.

    Existe um comando que por aí em GameModes chamado /Cores, que basicamente faz com que uma dialog MSGBOX apareça na tela do player com as 256 cores de veículos, cada cor com seu respectivo número, tipo isso:


    Mas pensa bem, se você for armazenar as 3072 caracteres que tem aí dentro (não é um palpite, têm exatos 3072 caracteres), você teria que fazer algo mais ou menos assim:
    Código PHP:
    Código:
    if(!strcmp(cmd, "/cores", true))
        {
             new color_list[3072];

            for (new colorid; colorid != sizeof gVehicleColors; colorid++)
            {
                format(color_list, sizeof color_list, "%s{%06x}%03d%s", color_list, gVehicleColors[colorid] >>> 8, colorid, !((colorid + 1) % 16) ? ("\n") : (" "));
            }
            ShowPlayerDialog(playerid, 1, DIALOG_STYLE_MSGBOX, "Color List", color_list, "Close", "");
            return 1;
        } 

    Sim, declarar uma string de 3072 cells, quero dizer 12.288bytes, exatos 12 KILOBYTES.
    Será se conseguimos diminuir para 3 KB? diminuir em 75%? Não exatamente, mas conseguimos diminuir muito a memória alocada, e é agora que começa o tutorial.

     Já que são 3072 caracteres, precisamos de apenas 768 cells (3072/4). Começamos por aí.
    Além disso, vamos ter que criar outra array para armazenar a string que será formatada (usaremos 14 cells).
    Por último, usaremos uma função.
    Código PHP:
    Código:
    if(!strcmp(cmd, "/Cores", true)) {
            new Result[768]; // Os 3072 caracteres do resultado final
            new String[14];     // Os 14 caracteres que serão formatados a cada looping
            for(new i; i != 256; ++i) { // 256 cores
                format(String, 14, "{%06x}%03i%s", (VehicleColors[i] >>> 8), i, (((i+1) % 16) ? (" ") : ("\n"))); // Não precisa entender isso, apenas que fique claro que estamos usando format
                strpack(String, String); // compactando as 14 cells em 14 bytes (que fique claro que a array String NÃO diminuiu de tamanho, apenas a informação foi compactada)
                strpackcat(Result, String); // juntando a array Result com a array String (formatada e depois compactada)
            } // Depois do processo ter terminado, a array Result estará prontinha para uso
            ShowPlayerDialog(playerid, DIALOG_NOANS, DIALOG_STYLE_MSGBOX, "Cores", Result, "Ok", "");
            return 1;
        } 


    a stock strpackcat (que basicamente concatena 2 packed strings, como se fosse strcat só que de packed strings):
    Código PHP:
    Código:
    stock strpackcat(dest[], const source[], maxlength=sizeof(dest)) {
        if(dest{3}) { if(!dest{0}) { print("JBScript [strpackcat] ERROR: The destiny string must be already packed before using this function."); return 0; } }
        if(source{3}) { if(!source{0}) { print("JBScript [strpackcat] ERROR: The source string must be already packed before using this function."); return 0; } }
        new dl = strlen(dest), sl = strlen(source);
        maxlength *= 4;
        if(maxlength < dl) { print("JBScript [strpackcat] ERROR: The maxlength is lesser then destiny string length."); return 0; }
        if(maxlength < sl+dl) { sl = maxlength-dl; }
        for(new i; i != sl; ++i) { dest{dl+i} = source{i}; }
        return 1;


    Bom, o tutorial é basicamente isso, não tão útil até porque nem sempre criamos uma array assim tão grande. É mais usado nesses casos (raros) mesmo.

    Algumas coisas eu não falei durante o tutorial pois não é o foco (já que devem existir outros tutoriais sobre os detalhes que eu deixei de falar, como o uso de 'char', que basicamente retorna o número de cells que são necessárias para armazenar x caracteres, etc).


    Créditos ao JohnBlack.



    Economia de memória para grandes Strings D07Xwqb
    Economia de memória para grandes Strings Yjab9HN

      Data/hora atual: Sex 17 maio 2024 - 22:43