SA-MP Forums Archive
Making a function faster - Printable Version

+- SA-MP Forums Archive (https://sampforum.blast.hk)
+-- Forum: SA-MP Scripting and Plugins (https://sampforum.blast.hk/forumdisplay.php?fid=8)
+--- Forum: Scripting Help (https://sampforum.blast.hk/forumdisplay.php?fid=12)
+--- Thread: Making a function faster (/showthread.php?tid=493968)



Making a function faster - CuervO - 10.02.2014

I've managed to do a function that renders any message and splits into next lines after a space was found starting from the 100th character of every line. The function itself was pretty fast, but I've added something that counts amount of color codes ({FFFFFF}) to carry the last one if found to the next line, this made the function extremly slow the way I made it (100k iterations = 27 Seconds); while I am not expert on this issue (yet) maybe we can work it out, this is the function:

pawn Код:
stock RenderMessage(top, color, const text[])
{
    new temp[156], tosearch = 0, colorint, posscolor, lastcol[12];
    new mess[356], colors, tempc; format(mess, 356, "%s",text);

    while(strlen(mess) > 0)
    {
        if(strlen(mess) < 140)
        {
            SendClientMessage(top, color, mess);
            break;
        }
   
        strmid(temp, mess, 0, 128);
        while(strfind(temp, "{", true) != -1)
        {
            tempc = strfind(temp, "{", true);
            if(temp[tempc+7] == '}')
            {
                colors ++;
                strdel(temp, tempc, tempc+7);
            }
            else
            {
                temp[tempc] = '0';
                continue;
            }
        }
        temp = "";
   
        if(strfind(mess," ",true,100+colors*8) != -1)
        {
            tosearch = strfind(mess," ",true,100+colors*8)+1;
            while(tosearch > 140)
            {
                colors --;
                tosearch = strfind(mess," ",true,100+colors*8)+1;
            }
        }
       
        if(strfind(mess,"{",true) != -1) //color codes detection , YAY
        {
            posscolor = strfind(mess,"{",true);

            if(mess[posscolor+7] == '}') //detected one color
                colorint = posscolor;
               
            while(strfind(mess,"{",true,colorint+1) != -1) //repeat until none are found
            {
                posscolor = strfind(mess,"{",true,colorint+1);
                if(posscolor > tosearch) //if next color will be on the other line, use last color found to render on the next line
                {
                    posscolor = colorint;
                    break;
                }
                if(mess[posscolor+7] == '}') //if found, then assign the color
                {
                    colorint = posscolor;
                }
                else
                {
                    posscolor = colorint; //else, leave the last color.
                    break;
                }
            }

            if(colorint == posscolor) //if the color position equals the one that was found
                strmid(lastcol,mess,colorint,colorint+8); //get the last used color string.
        }

        strmid(temp, mess, 0, tosearch);
        SendClientMessage(top, color, temp);
        strdel(mess, 0, tosearch);
        strins(mess, lastcol, 0); //insert last used color into the new line to be processed.


        temp = "";
        tosearch = 0;
        colors = 0;
    }
    return 1;
}
Inputs:

pawn Код:
RenderMessage(playerid, 0xFFFFFFFF, "{FFFF00}0123456789 0123456789 {FF0000}0123456789 0123456789 {00FF00}0123456789 0123456789 {0000FF}0123456789 0123456789 {FFFF00}0123456789 0123456789 {00FFFF}0123456789 0123456789 {FF6600}0123456789 0123456789 0123456789 {FF66FF}0123456789 {0066FF}0123456789 0123456789");
RenderMessage(playerid, 0xFFFFFFFF, "{FFFF00}0123456789 0123456789 {FF0000}0123456789 0123456789 {00FF00}0123456789 0123456789 {0000FF}0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 {FF6600}0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789");
RenderMessage(playerid, 0xFFFFFFFF, "{FFFF00}0123456789 0123456789 {FF0000}0123456789 0123456789 {00FF00}0123456789 0123456789 0123456789 0123456789 {FFFF00}0123456789 0123456789 0123456789 0123456789 {00FFFF}0123456789 0123456789 {FF0000}0123456789 0123456789 {0066FF}0123456789 0123456789 0123456789 0123456789 {FFFF00}0123456789 0123456789");
Output:



(the blank line is an empty message sent, not part of the function)


Код:
Input
RenderMessage(0, 0xFFFFFFFF, "{FFFF00}0123456789 0123456789 {FF0000}0123456789 0123456789 {00FF00}0123456789 0123456789 0123456789 0123456789 {FFFF00}0123456789 0123456789 0123456789 0123456789 {00FFFF}0123456789 0123456789 {FF0000}0123456789 0123456789 {0066FF}0123456789 0123456789 0123456789 0123456789 {FFFF00}0123456789 0123456789");

Outputs
Sent 10 messages in 3 MS
Sent 100 messages in 43 MS
Sent 1000 messages in 297 MS
Sent 10000 messages in 2772 MS
Sent 100000 messages in 27551 MS
(There's a RenderMessageToAll variation so RenderMessage wouldn't be used to send messages in a loop to (all) players.)


Re: Making a function faster - Mattakil - 10.02.2014

----


Re: Making a function faster - CuervO - 10.02.2014

Quote:
Originally Posted by Mattakil
Посмотреть сообщение
why not just use a dialog to enter the text?
That's not the point of the function;

Besides the dialogs inputtexts are just as long as the inputted text at the normal chat.

EDIT: saw you editted it! :P


Re: Making a function faster - Mattakil - 10.02.2014

Quote:
Originally Posted by CuervO
Посмотреть сообщение
That's not the point of the function;

Besides the dialogs inputtexts are just as long as the inputted text at the normal chat.

EDIT: saw you editted it! :P
Ya sorry, I didnt read it right.


Re: Making a function faster - CuervO - 10.02.2014

I've added some benchmarkings (not using any special methods so it's not 100% accurate but you can get the idea of how slow can the function get).

1000000 renderings will take around 270000 MS


Re: Making a function faster - Pottus - 10.02.2014

It's still not slow enough to really cause any sort of bottle neck I would think it's actually kind of silly to measure it against complete impossibility of 100,0000 iterations when you'll probably have no more than a dozen during any given one second period.

For starters however you can do this to eliminate a redundant check.

pawn Код:
if(strlen(mess) < 140) SendClientMessage(top, color, mess);
    else
    {
@Edit - I understand fully it is slow so it would be nice to make it faster.


Re: Making a function faster - CuervO - 10.02.2014

Quote:
Originally Posted by [uL]Pottus
Посмотреть сообщение
It's still not slow enough to really cause any sort of bottle neck I would think it's actually kind of silly to measure it against complete impossibility of 100,0000 iterations when you'll probably have no more than a dozen during any given one second period.
Well, I was wondering if it could get any faster;

And what you said is completely true too, nevertheless I still don't think the function is made in a very efficent way :P, and I would like to release it as a snippet or something, there aren't really many (if any) line splitter functions around here