[Tutorial] Creative & smart scripting techniques - improve performance & readablity in one go
#21

Probably misinterpretation once again.

In the topic I was talking about using memcpy vs assiging everything manually. Memcpy is nearly 50x+ (depends on the array and size) faster than assigning values manually. Also, its more neat and readable.

That performance improvement is significant especially when you have large arrays/enum arrays. It is a WIN-WIN scenario (readability + performance)!

Somebody asked if using memcpy was faster than assigning an array directly and I just gave an explanation.
Reply
#22

Quote:
Originally Posted by Yashas
View Post
Probably misinterpretation once again.

In the topic I was talking about using memcpy vs assiging everything manually. Memcpy is nearly 50x+ (depends on the array and size) faster than assigning values manually. Also, its more neat and readable.

That performance improvement is significant especially when you have large arrays/enum arrays. It is a WIN-WIN scenario (readability + performance)!

Somebody asked if using memcpy was faster than assigning an array directly and I just gave an explanation.
Sorry to break this to you, but no-one in productional terms gives a damn about performance as long as it is decent and it works.

Start seeing things how they really are, and don't waste your time on insignificant improvements.

This is a bit ridiculous, will you ever talk about something else or will we keep seeing "faster" on each reply you create?

Setting variables, arrays, w/e is already fast. 50,000 iterations = 1ms.
Reply
#23

I have no words for that.

The ideas mentioned in this thread improve readability too. Would you use a for loop when you can do it nicely with a switch in your code? Would you bloat your OnPlayerConnect when you can do it neatly in one line?

Are you going to use DCMD? Its not just performance, its about readability too and the ones mentioned in this topic are not really insignificant.

Of course, sometimes every reply I make will have something which makes the given code faster. I just tell it. I don't mention it in the thread because it is insignificant. When someone asks, I answer them so that I can help people learn. In fact, you will find explanations in most of my replies and they also contain extra information. The purpose is to help people understand better, in other words, give more insight into the issue/problem/idea.
Reply
#24

Hey Yashas, thank you for this useful & helpful knowledge you've shared to the community. keep it up

I'm having an error and a warning though, need help on this..

warning 229: index tag mismatch (symbol "pInfo")
error 032: array index out of bounds (variable "pInfo")

both on the same line which is
Quote:

memcpy(pInfo[playerid], pInfo[MAX_PLAYERS], 0, sizeof(pInfo[])*4, sizeof(pInfo[]));

^ that one

Quote:

enum PlayerInfo
{
Pass[129],
Admin,
Helper,
Level,
Exp,
ExpLeft,
Score,
Wanted,
Prison,
Donator,

FactionID,
FactionTier,
FactionRank[30],

HouseOwner,
CarOwner,
BizOwner,

Weapon1,
Weapon1Ammo,
Weapon2,
Weapon2Ammo,
Weapon3,
Weapon3Ammo,

Material,
Drug,
C4,

HandMoney,
BankMoney,

Kills,
Deaths,

Arrest,
Arrested,

TicketFine,
Ticketted,

Hours,
Minutes,
Seconds,


FightStyle,
Mask,
SkinID
};

new pInfo[MAX_PLAYERS][PlayerInfo];

Reply
#25

1.
Code:
new pInfo[MAX_PLAYERS + 1][PlayerInfo];
2. I don't know for what is here memcpy
Code:
pInfo[playerid] = pInfo[MAX_PLAYERS];
Reply
#26

This
PHP Code:
new Float:Coords[5][4] = {
    {
0.00.10.20.3},
    {
1.01.11.21.3},
    {
2.02.12.22.3},
    {
3.03.13.23.3},
    {
4.04.14.24.3}
};
function(){
    new 
rand random(sizeof(Coords));
    foreach(new 
iPlayer)
    {
        
SetPlayerPos(playeridCoords[rand][0], Coords[rand][1], Coords[rand][2]);
        
SetPlayerFacingAngle(playeridCoords[rand][3]);
    }
    
CreatePickup(12Coords[rand][0], Coords[rand][1], Coords[rand][2]);
    
Create3DTextLabel("You are here", -1Coords[rand][0], Coords[rand][1], Coords[rand][2], 15.00);

is Slower than this
PHP Code:
new Float:Coords[5][4] = {
    {
0.00.10.20.3},
    {
1.01.11.21.3},
    {
2.02.12.22.3},
    {
3.03.13.23.3},
    {
4.04.14.24.3}
};
function(){
    new 
rand random(sizeof(Coords));
    new 
        
Float:X        Coords[rand][0],
        
Float:Y        Coords[rand][1],
        
Float:Z        Coords[rand][2],
        
Float:Ang    Coords[rand][3]
    ;
    foreach(new 
iPlayer)
    {
        
SetPlayerPos(playeridXYZ);
        
SetPlayerFacingAngle(playeridCoords[rand][3]);
    }
    
CreatePickup(12XYZ);
    
Create3DTextLabel("You are here", -1XYZ15.00);

The functions are example.

I think, because every time at Coords[*] is called, need load the value i and the value from Coords, if you use the array only a time no have differences between speed.

Sorry my bad english, someone smarter than me can explain better.
Reply
#27

new gPlayerInfo[MAX_PLAYERS][PlayerData];
new playerInfo[PlayerData];

gPlayerInfo[playerid]=playerInfo;

is not function memcpy is pawn faster than function memcpy
Reply
#28

  1. If you are looking for a only one symbol, it is better to use a loop.
  2. If necessary to use a for loop for the whole string, it is not necessary to know the size of the string.


    PHP Code:
    new string[128] = "qw;lasdl;k1l;k2l;4k;"// :D
    for (new i/* none */ ;i++)
    {
        if (
    string[i] == 'l')
        {
            
    // do something
            // ...
            // loop is complete
            
    break;
        }
        
    // cycle is complete
        // if symbol is not found
        
    if (string[i] == '\0')
        {
            break;
        }

    or

    PHP Code:
    new string[128] = "qw;lasdl;k1l;k2l;4k;",
        
    i;
    while (
    string[i++] != '\0')
    {
        if (
    string[i] == 'l')
        {        
            
    // do something
            // ...
            // loop is complete
            
    break;
        }

  3. For more optimization you can use variables, so often not to refer to the array index.

    PHP Code:
    new string[128] = "qw;lasdl;k1l;k2l;4k;"
        
    c,    // is values of the array index 
        
    i     // index 

    while ((
    string[i++]) != '\0')
    {
        if (
    == 'l')
        {        
            
    // do something
            // ...
            // loop is complete
            
    break;
        }

  4. If the condition need to compare three numbers, it is possible to make it so
    PHP Code:
    new value 7;
    if (
    <= value <= 9)
    {
        
    // do something

Reply
#29

the second code is wrong because ++ but just use strfind
Reply
#30

Quote:
Originally Posted by OneDay
View Post
the second code is wrong because ++ but just use strfind
No, it's not wrong. Learn PAWN before trying to call someone out like that.
Reply
#31

Quote:
Originally Posted by Crayder
View Post
No, it's not wrong. Learn PAWN before trying to call someone out like that.
i do know pawn but help for to advertise

Code:
new string[128] = "laa",
    i; // i = 0

while (string[i++] != '\0') // string[i] = 'l', i++ = 1
{
    if (string[i] == 'l') // i = 1, string[i] = 'a'
    {        
        // never done
        break;
    }
}
first 'l' missed
Reply
#32

Quote:
Originally Posted by Jefff
View Post
1.
Code:
new pInfo[MAX_PLAYERS + 1][PlayerInfo];
2. I don't know for what is here memcpy
Code:
pInfo[playerid] = pInfo[MAX_PLAYERS];
memcpy is actually faster that direct assignment when your array is VERY BIG.

Quote:
Originally Posted by Uberanwar
View Post
Hey Yashas, thank you for this useful & helpful knowledge you've shared to the community. keep it up

I'm having an error and a warning though, need help on this..

warning 229: index tag mismatch (symbol "pInfo")
error 032: array index out of bounds (variable "pInfo")

both on the same line which is

^ that one
I guess its because of the sizeof, try sizeof(pInfo[][]) or something similar. I have lost touch with PAWN and I do not remember. A bit of tweaking should fix the problem.


Quote:
Originally Posted by Day_
View Post
This
PHP Code:
new Float:Coords[5][4] = {
    {
0.00.10.20.3},
    {
1.01.11.21.3},
    {
2.02.12.22.3},
    {
3.03.13.23.3},
    {
4.04.14.24.3}
};
function(){
    new 
rand random(sizeof(Coords));
    foreach(new 
iPlayer)
    {
        
SetPlayerPos(playeridCoords[rand][0], Coords[rand][1], Coords[rand][2]);
        
SetPlayerFacingAngle(playeridCoords[rand][3]);
    }
    
CreatePickup(12Coords[rand][0], Coords[rand][1], Coords[rand][2]);
    
Create3DTextLabel("You are here", -1Coords[rand][0], Coords[rand][1], Coords[rand][2], 15.00);

is Slower than this
PHP Code:
new Float:Coords[5][4] = {
    {
0.00.10.20.3},
    {
1.01.11.21.3},
    {
2.02.12.22.3},
    {
3.03.13.23.3},
    {
4.04.14.24.3}
};
function(){
    new 
rand random(sizeof(Coords));
    new 
        
Float:X        Coords[rand][0],
        
Float:Y        Coords[rand][1],
        
Float:Z        Coords[rand][2],
        
Float:Ang    Coords[rand][3]
    ;
    foreach(new 
iPlayer)
    {
        
SetPlayerPos(playeridXYZ);
        
SetPlayerFacingAngle(playeridCoords[rand][3]);
    }
    
CreatePickup(12XYZ);
    
Create3DTextLabel("You are here", -1XYZ15.00);

The functions are example.

I think, because every time at Coords[*] is called, need load the value i and the value from Coords, if you use the array only a time no have differences between speed.

Sorry my bad english, someone smarter than me can explain better.
It is well explained here (Click) with proof.

Quote:
Originally Posted by OneDay
View Post
new gPlayerInfo[MAX_PLAYERS][PlayerData];
new playerInfo[PlayerData];

gPlayerInfo[playerid]=playerInfo;

is not function memcpy is pawn faster than function memcpy
IIRC memcpy is faster when the array is pretty huge. The improvement is however negligible since either way its WAY WAY WAY faster than the loop method to reset an array (the speed difference b/w memcpy and direct assignment doesn't matter here - I have explained it in on of my previous replies to SickAttack).

Quote:
Originally Posted by Untonyst
View Post
  1. If you are looking for a only one symbol, it is better to use a loop.
  2. If necessary to use a for loop for the whole string, it is not necessary to know the size of the string.


    PHP Code:
    new string[128] = "qw;lasdl;k1l;k2l;4k;"// :D
    for (new i/* none */ ;i++)
    {
        if (
    string[i] == 'l')
        {
            
    // do something
            // ...
            // loop is complete
            
    break;
        }
        
    // cycle is complete
        // if symbol is not found
        
    if (string[i] == '\0')
        {
            break;
        }

    or

    PHP Code:
    new string[128] = "qw;lasdl;k1l;k2l;4k;",
        
    i;
    while (
    string[i++] != '\0')
    {
        if (
    string[i] == 'l')
        {        
            
    // do something
            // ...
            // loop is complete
            
    break;
        }

  3. For more optimization you can use variables, so often not to refer to the array index.

    PHP Code:
    new string[128] = "qw;lasdl;k1l;k2l;4k;"
        
    c,    // is values of the array index 
        
    i     // index 

    while ((
    string[i++]) != '\0')
    {
        if (
    == 'l')
        {        
            
    // do something
            // ...
            // loop is complete
            
    break;
        }

  4. If the condition need to compare three numbers, it is possible to make it so
    PHP Code:
    new value 7;
    if (
    <= value <= 9)
    {
        
    // do something

Your loop is horribley slow compared to strfind. Strfind accepts a substring instead of a character but its still faster when you want to search for a character.

Check Natives are faster than PAWN code in this (Click)topic to know more.

Quote:
Originally Posted by OneDay
View Post
the second code is wrong because ++ but just use strfind
1. strfind is faster than that code
2. His code has a bug. It skips a character.

Quote:
Originally Posted by Crayder
View Post
No, it's not wrong. Learn PAWN before trying to call someone out like that.
His English isn't good lol

He wanted to say that there is a bug and that code wont work because of i++ but he said it in a completely wrong and misleading way.
Reply
#33

thank you
Reply
#34

Thanks for the useful info in this thread
Reply
#35

so strange there is no info about GetPlayerPing
GetPlayerPing=loop for 1000
Reply
#36

Quote:
Originally Posted by SPAWN_METAL
View Post
so strange there is no info about GetPlayerPing
GetPlayerPing=loop for 1000
Why would someone loop GetPlayerPing times?
Reply
#37

I get a tag mismatch:
Code:
#include <a_samp>

enum PlayerInfo_t
{
      Name[MAX_PLAYER_NAME],
      MoneyInHand,
      BankMoney,
      Team,
      Skin,
      Kills,
      Deaths,
      WantedLevel,
      AdminLevel,
      Muted,
      Jailed,
      Frozen      
}
new PlayerInfo[MAX_PLAYERS + 1][PlayerInfo_t];

public OnGameModeInit()
{
      PlayerInfo[MAX_PLAYERS][Team] = -1;
      PlayerInfo[MAX_PLAYERS][Skin] = 1;
      PlayerInfo[MAX_PLAYERS][MoneyInHand] = 
      PlayerInfo[MAX_PLAYERS][BankMoney] = 
      PlayerInfo[MAX_PLAYERS][Kills] = 
      PlayerInfo[MAX_PLAYERS][Deaths] =
      PlayerInfo[MAX_PLAYERS][WantedLevel] = 
      PlayerInfo[MAX_PLAYERS][AdminLevel] =  0;
      PlayerInfo[MAX_PLAYERS][Muted] = true;
      PlayerInfo[MAX_PLAYERS][Jailed] =
      PlayerInfo[MAX_PLAYERS][Frozen] =  false;
      return 1;
}

public OnPlayerConnect(playerid)
{
      memcpy(PlayerInfo[playerid], PlayerInfo[MAX_PLAYERS], 0, sizeof(PlayerInfo[])*4, sizeof(PlayerInfo[]));
      return 1;
}
Reply
#38

Quote:
Originally Posted by Yashas
View Post
Why would someone loop GetPlayerPing times?
loop in GetPlayerPing
Reply
#39

Code:
public OnPlayerConnect(playerid)
{
      memcpy(PlayerInfo[playerid], PlayerInfo[MAX_PLAYERS], 0, sizeof(PlayerInfo[])*4, sizeof(PlayerInfo[]));
}
ayy, double tag mismatch
Reply
#40

Quote:
Originally Posted by Kaperstone
View Post
Code:
public OnPlayerConnect(playerid)
{
      memcpy(PlayerInfo[playerid], PlayerInfo[MAX_PLAYERS], 0, sizeof(PlayerInfo[])*4, sizeof(PlayerInfo[]));
}
ayy, double tag mismatch
The reason for index tag mismatch is that the second dimension of the PlayerInfo array expects the index to have the tag PlayerInfo_t but the memcpy argument does not expect any tag.

Possible fixes:
  1. Code:
    public OnPlayerConnect(playerid)
    {
          memcpy(PlayerInfo[playerid][PlayerInfo_t:0], PlayerInfo[MAX_PLAYERS][PlayerInfo_t:0], 0, sizeof(PlayerInfo[])*4, sizeof(PlayerInfo[]));
    }
  2. Use playerInfo_t instead of PlayerInfo_t. This would resolve the warning because weak tags are convertible to _:.
  3. Do direct assignment:
    Code:
    PlayerInfo[playerid] = PlayerInfo[MAX_PLAYERS];
Thanks for pointing out.
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)