01.10.2011, 22:07
Por que vocк nгo deve usar strings grandes de 256 celulas
Originalmente postado por ****** (Topico)
Нndice
- Нndice
- Introduзгo
- Resumo
- Porque nгo devemos usar 256?
- Й lento!
- Vocк nгo precisa (1)
- O maior tamanho de entrada й 128
- O maior tamanho de saнda й 128
- Vocк nгo precisa (2)
- Uso de stack
- Packed Strings
- Quando eu posso usar 256?
- SQL
- Leitura de arquivos
- Conclusгo
Introduзгo
As pessoas tкm alguns ESTRANHISSIMOS costumes sobre strings em PAWN, a maioria tem a ver com seus tamanhos. Muitas pessoas pensam que uma string nгo pode ser maior que 256, o porquк, eu nгo sei, parece como se fosse imposto um limite que nгo й necessбrio e de fato nгo existe limite algum. Outras pessoas pensam que todas as strings tem que ser de 256 por nenhuma razгo aparente, nгo importa o quгo longa serб sua string. Uma string em PAWN й exatamente o mesmo que qualquer outra array, as pessoas nгo tem nenhum problema com outras arrays, entгo porque strings?
*Nota-se que a algumas pessoas usam 255 no lugar de 256, mas estes sгo tгo escrotos quanto os outros.
Resumo
Uma string em PAWN й apenas uma array de caracteres, nenhuma diferenзa com outras arrays. Strings sгo terminadas em NULL, isso quer dizer que todas tem o caracter '\0' (null) no fim (cуdigo 0 na tabela ASCII, diferente do caractere '0' o qual й o cуdigo 48 da tabela ASCII). Se vocк tem a seguinte string:
pawn Код:
new
str[3] = "hi";
pawn Код:
new
str[3] = {'h', 'i', '\0'};
pawn Код:
new
str[3] = {104, 105, 0};
Em PAWN todas as variбveis sгo setadas para 0 quando sгo declaradas, isso quer dizer que quando vocк faz:
pawn Код:
new
str[256];
pawn Код:
new
str[256];
for (new i = 0; i < 256; i++)
{
str[i] = 0;
}
Por que nгo devo usar 256?
- Й lento
- Vocк nгo precisa disso (1)
Quote:
Originally Posted by X_Cutterz
stock ReturnModeratorCmd(playerid,reqlvl)
{ new rmcmd[256]; format(rmcmd,sizeof(rmcmd),"Only moderators level %d+ can use this command!",reqlvl); return SendClientMessage(playerid,Green,rmcmd); } |
Pelas minhas contas ali tem 47 caracteres na string, 2 deles sгo o "%d" que nгo aparece na contagem final da string, entгo por fim restam 45. Nos jб sabemos que o maior numero serб 4 (se vocк quer ter REALMENTE certeza de proteger o nнvel de admin, o maior numero possнvel em PAWN й 11 caracteres (-2147483647)), e nos sabemos que todas as strings requerem o NULL no fim, entгo o mais longo possнvel que esta string pode ser й:
47 - 2 + 4 + 1 = 50
50 cйlulas, entгo porque usar 256, й uma perda de 206 cйlulas (824 bytes - que chega perto de uma perda de 1 kilobyte de memoria)?
- O mбximo de tamanho de entrada й 128
[anchor=o128]
- O mбximo de tamanho de saнda й 128
- Vocк nгo precisa disso (2)
pawn Код:
public OnPlayerCommandText(playerid, cmdtext[])
{
new
string[256],
cmd[256];
cmd = strtok(cmdtext, idx);
if (strcmp(cmd, "/num", true) == 0)
{
format(string, sizeof (string), "Random number: %d", random(27));//traduзгo da mensagem "Numero randomico: %d"
SendClientMessage(playerid, 0xFF0000AA, string);
}
}
pawn Код:
new
string[256],
cmd[256];
pawn Код:
new
string[256];
Uma versгo mais eficiente poderia ser:
pawn Код:
public OnPlayerCommandText(playerid, cmdtext[])
{
new
string[128]; // cmdtext NUNCA sera maior que 128
string = strtok(cmdtext, idx);
if (strcmp(string, "/num", true) == 0)
{
format(string, sizeof (string), "Random number: %d", random(27)); // Sу precisamos de 18 caracteres aqui, mas serб necessбrio 128 futuramente entгo o tamanho da variбvel й justificado
SendClientMessage(playerid, 0xFF0000AA, string);
}
}
- O uso de stack
Exemplo:
pawn Код:
new
gVar = 2;
stock StackUse()
{
new
str[9];
format(str, sizeof (str), "gVar = %d", gVar);
SendClientMessageToAll(0xFF0000AA, str);
if (gVar)
{
gVar--;
StackUse();
}
}
Agora imagine este cуdigo:
pawn Код:
new
gVar = 2;
stock StackUse()
{
new
str[256];
format(str, sizeof (str), "gVar = %d", gVar);
SendClientMessageToAll(0xFF0000AA, str);
if (gVar)
{
gVar--;
StackUse();
}
}
Alguns de vocкs devem ter visto esta mensagem (ou uma parecida) quando compilam:
Код:
Header size: 216 bytes Code size: 776 bytes Data size: 528 bytes Stack/heap size: 16384 bytes; estimated max. usage: unknown, due to recursion Total requirements: 17904 bytes
Код:
Header size: 200 bytes Code size: 588 bytes Data size: 512 bytes Stack/heap size: 16384 bytes; estimated max. usage=10250 cells (41000 bytes) Total requirements: 17684 bytes
O primeiro erro que eu postei quer dizer que vocк esta tentando usar mais stack do que й disponнvel, mas por isso tem algumas funзхes chamando elas mesmas e o compilador nгo pode dizer exatamente quanto vocк precisa. Note que o compilador nгo pode determinar quantas vezes uma funзгo pode chamar ela mesma, mesmo no exemplo acima, o numero pode mudar em algum lugar do programa, e geralmente nгo й uma constante de qualquer jeito. O segundo erro й gerado pelo programa sem exatidгo.
Isso se aplica a TODAS arrays, mas strings sгo as maiores culpadas.
Packed Strings
Um aspecto de PAWN raramente usado em SA:MP (devido а algumas natives nгo suporta-la) й a 'Packed Strings'. Strings normais guardam um caractere por cйlula e uma cйlula possui o tamanho de 4 bytes (fazendo cйlulas de 256 da exatamente o tamanho de 1 kilobyte), packed strings guardam 4 caracteres por cйlulas:
Nгo packed:
pawn Код:
new
string[12] = "Hello there"; // 12 celulas, 48 bytes
pawn Код:
new
string[12 char] = !"Hello there"; // 3 celulas, 12 bytes
Quando eu posso usar 256?
Tendo dito tudo isto, ainda tem vezes que o uso de grandes arays podem ser uteis, mas elas devem ser usadas com moderaзгo somente quando necessбrias.
- SQL
- Lendo arquivos
Conclusгo
"Em caso de duvida - nгo entendeu algo". Sгo MUITO poucos os casos em que usa-se strings pesadas, pense sobre o que vocк faz para determinar o tamanho de qualquer array, baseado nisto, aplique o mesmo processo em strings.