[Plugin] GVar Plugin
#81

Very good work.Keep up the good work Incognito.
Reply
#82

Nice incognito
Reply
#83

Firstly: I know that this looks really really stupid, but I needed to test this plugin under really heavy stress (lots of huge string writing per second), because I have a thing in my mind to script in the future which uses this plugin a lot (SetGVarString), and I want to be sure it handles lots of messages being written in memory.

Code:
pawn Код:
for( new i = 0; i < 10000; i ++ )
{
    SetGVarString( "HugeMessageForShowOff", gsBigString, i );
    printf( "%d", i );
}
for( new i = 0; i < 10000; i ++ )
{
    SetGVarString( "HugeMessageForShowOff", gsBigString, i );
    printf( "%d", i );
}
(gsBigString is a string with size ~8300, currently around 7300 characters were used to be written)

When I first "loadfs" in console, it writes fine in memory (verified using task manager), but after few more "reloadfs", it takes only few more kilobytes/megabytes (which is ok), but after ~10 "reloadfs" it starts giving these:
pawn Код:
[11/01/2015 23:36:57] [debug] Run time error 7: "Stack underflow"
[11/01/2015 23:36:57] [debug]  Stack pointer (STK) is 0x4076BC, stack top (STP) is 0x4076BC
[11/01/2015 23:36:57] [debug] AMX backtrace:
[11/01/2015 23:36:57] [debug] Run time error 7: "Stack underflow"
[11/01/2015 23:36:57] [debug]  Stack pointer (STK) is 0x4076BC, stack top (STP) is 0x4076BC
[11/01/2015 23:36:57] [debug] AMX backtrace:
[11/01/2015 23:36:57] [debug] Run time error 7: "Stack underflow"
[11/01/2015 23:36:57] [debug]  Stack pointer (STK) is 0x4076BC, stack top (STP) is 0x4076BC
[11/01/2015 23:36:57] [debug] AMX backtrace:
[11/01/2015 23:36:57] [debug] Run time error 7: "Stack underflow"
[11/01/2015 23:36:57] [debug]  Stack pointer (STK) is 0x4076BC, stack top (STP) is 0x4076BC
[11/01/2015 23:36:57] [debug] AMX backtrace:
[11/01/2015 23:36:57] [sampgdk] error: Too many callback arguments (at most 32 allowed)
[11/01/2015 23:36:57] [debug] Run time error 7: "Stack underflow"
[11/01/2015 23:36:57] [debug]  Stack pointer (STK) is 0x4076BC, stack top (STP) is 0x4076BC
[11/01/2015 23:36:57] [debug] AMX backtrace:
[11/01/2015 23:36:57] [sampgdk] error: Too many callback arguments (at most 32 allowed)
over and over without it crashing the server. I see that this is also a sampGDK problem.

(if I use just one big loop with that gsBigString, it starts giving errors after a few thousands, but at ~90000 (maximum at 99999) it crashes the server)

When I tried it with a timer:
pawn Код:
SetTimerEx( "WorkTimer", 2_000, 0, "i", 0 ); // OnFilterScriptInit

forward WorkTimer( number );
public WorkTimer( number )
{
    for( new i = number; i < number+10000; i ++ )
    {
        SetGVarString( "HugeMessageForShowOff", gsBigString, i );
        printf( "%d", i );
    }
    number = number+10000;
    SetTimerEx( "WorkTimer", 2_000, 0, "i", number );
    return 1;
}
it crashed after "221102":
pawn Код:
[11/01/2015 23:52:15] [debug] Server crashed while executing maps.amx
[11/01/2015 23:52:15] [debug] AMX backtrace:
[debug] #0 native SetGVarString () from gvar.DLL
[debug] #1 000018ec in public WorkTimer (0x00035b60) from maps.amx
[11/01/2015 23:52:15] [debug] // no information being printed at this debug
(I had more RAM available, 5gb were used out of 8gb)

I want to know if this can be solved, or if I should stay at testing it less agressive.
Reply
#84

Quote:
Originally Posted by IstuntmanI
Посмотреть сообщение
Firstly: I know that this looks really really stupid, but I needed to test this plugin under really heavy stress (lots of huge string writing per second), because I have a thing in my mind to script in the future which uses this plugin a lot (SetGVarString), and I want to be sure it handles lots of messages being written in memory.

Code:
pawn Код:
for( new i = 0; i < 10000; i ++ )
{
    SetGVarString( "HugeMessageForShowOff", gsBigString, i );
    printf( "%d", i );
}
for( new i = 0; i < 10000; i ++ )
{
    SetGVarString( "HugeMessageForShowOff", gsBigString, i );
    printf( "%d", i );
}
(gsBigString is a string with size ~8300, currently around 7300 characters were used to be written)

When I first "loadfs" in console, it writes fine in memory (verified using task manager), but after few more "reloadfs", it takes only few more kilobytes/megabytes (which is ok), but after ~10 "reloadfs" it starts giving these:
pawn Код:
[11/01/2015 23:36:57] [debug] Run time error 7: "Stack underflow"
[11/01/2015 23:36:57] [debug]  Stack pointer (STK) is 0x4076BC, stack top (STP) is 0x4076BC
[11/01/2015 23:36:57] [debug] AMX backtrace:
[11/01/2015 23:36:57] [debug] Run time error 7: "Stack underflow"
[11/01/2015 23:36:57] [debug]  Stack pointer (STK) is 0x4076BC, stack top (STP) is 0x4076BC
[11/01/2015 23:36:57] [debug] AMX backtrace:
[11/01/2015 23:36:57] [debug] Run time error 7: "Stack underflow"
[11/01/2015 23:36:57] [debug]  Stack pointer (STK) is 0x4076BC, stack top (STP) is 0x4076BC
[11/01/2015 23:36:57] [debug] AMX backtrace:
[11/01/2015 23:36:57] [debug] Run time error 7: "Stack underflow"
[11/01/2015 23:36:57] [debug]  Stack pointer (STK) is 0x4076BC, stack top (STP) is 0x4076BC
[11/01/2015 23:36:57] [debug] AMX backtrace:
[11/01/2015 23:36:57] [sampgdk] error: Too many callback arguments (at most 32 allowed)
[11/01/2015 23:36:57] [debug] Run time error 7: "Stack underflow"
[11/01/2015 23:36:57] [debug]  Stack pointer (STK) is 0x4076BC, stack top (STP) is 0x4076BC
[11/01/2015 23:36:57] [debug] AMX backtrace:
[11/01/2015 23:36:57] [sampgdk] error: Too many callback arguments (at most 32 allowed)
over and over without it crashing the server. I see that this is also a sampGDK problem.

(if I use just one big loop with that gsBigString, it starts giving errors after a few thousands, but at ~90000 (maximum at 99999) it crashes the server)

When I tried it with a timer:
pawn Код:
SetTimerEx( "WorkTimer", 2_000, 0, "i", 0 ); // OnFilterScriptInit

forward WorkTimer( number );
public WorkTimer( number )
{
    for( new i = number; i < number+10000; i ++ )
    {
        SetGVarString( "HugeMessageForShowOff", gsBigString, i );
        printf( "%d", i );
    }
    number = number+10000;
    SetTimerEx( "WorkTimer", 2_000, 0, "i", number );
    return 1;
}
it crashed after "221102":
pawn Код:
[11/01/2015 23:52:15] [debug] Server crashed while executing maps.amx
[11/01/2015 23:52:15] [debug] AMX backtrace:
[debug] #0 native SetGVarString () from gvar.DLL
[debug] #1 000018ec in public WorkTimer (0x00035b60) from maps.amx
[11/01/2015 23:52:15] [debug] // no information being printed at this debug
(I had more RAM available, 5gb were used out of 8gb)

I want to know if this can be solved, or if I should stay at testing it less agressive.
Did you remove the var on OnFilterScriptExit?

Quote:
Notes
  • Remember to delete GVars when they are no longer needed, particularly when a gamemode or filterscript exits.
  • The optional ID, like the player ID in PVars, must be unique.
  • GVar names are case-insensitive.
Reply
#85

Quote:
Originally Posted by Crayder
Посмотреть сообщение
Did you remove the var on OnFilterScriptExit?
This is not really required, it's just a suggestion, to free the memory. This is not the point.
Reply
#86

amazing plugin. +rep
Reply
#87

Can anyone help?
https://sampforum.blast.hk/showthread.php?tid=565407
Reply
#88

Can someone give a good tutorial on it or explain how it works.
Reply
#89

PHP код:
    if (GetGVarInt("g_MySQLcon") == 1)
        return 
0
It just make compiler crash, how to use it ._.
Reply
#90

I thought for a while about it, but I thought that it would be denied from the start, but ... well ... I should try to give this suggestion, it looks useful:

What about 2 IDs per-function ? For example
pawn Код:
native SetGVarInt(const name[], value, id = 0);
would add a new default 0 id parameter:
pawn Код:
native SetGVarInt(const name[], value, id = 0, id2 = 0);
Why ? Well ... for when we need two IDs, of course. The best examples I can give are the house items, the first ID would be house id, and the second ID would be the item id in that house.

For example:
pawn Код:
format( gsString, 64, "HouseItemBuyPrice%d", houseid );
SetGVarInt( gsString, 10000, itemid );
would become:
pawn Код:
SetGVarInt( "HouseItemBuyPrice", 10000, houseid, itemid );
Reply
#91

Just letting you know that server variables are a thing as of 0.3.7 R2
Reply
#92

Quote:
Originally Posted by KingHual
Посмотреть сообщение
Just letting you know that server variables are a thing as of 0.3.7 R2
I know, *cough* with no ID *cough*.
Reply
#93

I'm too lazy. Somebody please test SVar vs GVar speed. Thanks
Reply
#94

Quote:
Originally Posted by kurta999
Посмотреть сообщение
I'm too lazy. Somebody please test SVar vs GVar speed. Thanks
Code used:
pawn Код:
public OnFilterScriptInit( )
{
    new liTick;

    #define ITERS 1000000

    //============================[ Set Int ]===================================
    // GVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        SetGVarInt( "TestSI", 69 );

    printf( "INT: Set: GVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    // SVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        SetSVarInt( "TestSI", 69 );

    printf( "INT: Set: SVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    //============================[ Get Int ]===================================
    // GVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        GetGVarInt( "TestGI" );

    printf( "INT: Get: GVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    // SVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        GetSVarInt( "TestGI" );

    printf( "INT: Get: SVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    //===========================[ Set Float ]==================================
    // GVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        SetGVarFloat( "TestSF", 69.00 );

    printf( "FLOAT: Set: GVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    // SVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        SetSVarFloat( "TestSF", 69.00 );

    printf( "FLOAT: Set: SVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    //===========================[ Get Float ]==================================
    // GVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        GetGVarFloat( "TestGF" );

    printf( "FLOAT: Get: GVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    // SVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        GetSVarFloat( "TestGF" );

    printf( "FLOAT: Get: SVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    //===========================[ Set String ]=================================
    // GVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        SetGVarString( "TestSS", "Sixty Nine" );

    printf( "STRING: Set: GVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    // SVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        SetSVarString( "TestSS", "Sixty Nine" );

    printf( "STRING: Set: SVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    //===========================[ Get String ]=================================
    new lsString[ 16 ];

    // GVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        GetGVarString( "TestGS", lsString, 16 );

    printf( "STRING: Get: GVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    // SVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        GetSVarString( "TestGS", lsString, 16 );

    printf( "STRING: Get: SVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    return 1;
}
Results:
Quote:

INT: Set: GVar speed for 1000000 iterations: 237ms
INT: Set: SVar speed for 1000000 iterations: 170ms

INT: Get: GVar speed for 1000000 iterations: 234ms
INT: Get: SVar speed for 1000000 iterations: 162ms


FLOAT: Set: GVar speed for 1000000 iterations: 229ms
FLOAT: Set: SVar speed for 1000000 iterations: 179ms

FLOAT: Get: GVar speed for 1000000 iterations: 218ms
FLOAT: Get: SVar speed for 1000000 iterations: 167ms


STRING: Set: GVar speed for 1000000 iterations: 309ms
STRING: Set: SVar speed for 1000000 iterations: 344ms

STRING: Get: GVar speed for 1000000 iterations: 223ms
STRING: Get: SVar speed for 1000000 iterations: 175ms

So SVars are slower only at setting strings.
Reply
#95

Thanks. GVars works anyway totally different.
Reply
#96

Quote:
Originally Posted by IstuntmanI
Посмотреть сообщение
Code used:
pawn Код:
public OnFilterScriptInit( )
{
    new liTick;

    #define ITERS 1000000

    //============================[ Set Int ]===================================
    // GVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        SetGVarInt( "TestSI", 69 );

    printf( "INT: Set: GVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    // SVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        SetSVarInt( "TestSI", 69 );

    printf( "INT: Set: SVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    //============================[ Get Int ]===================================
    // GVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        GetGVarInt( "TestGI" );

    printf( "INT: Get: GVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    // SVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        GetSVarInt( "TestGI" );

    printf( "INT: Get: SVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    //===========================[ Set Float ]==================================
    // GVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        SetGVarFloat( "TestSF", 69.00 );

    printf( "FLOAT: Set: GVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    // SVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        SetSVarFloat( "TestSF", 69.00 );

    printf( "FLOAT: Set: SVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    //===========================[ Get Float ]==================================
    // GVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        GetGVarFloat( "TestGF" );

    printf( "FLOAT: Get: GVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    // SVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        GetSVarFloat( "TestGF" );

    printf( "FLOAT: Get: SVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    //===========================[ Set String ]=================================
    // GVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        SetGVarString( "TestSS", "Sixty Nine" );

    printf( "STRING: Set: GVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    // SVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        SetSVarString( "TestSS", "Sixty Nine" );

    printf( "STRING: Set: SVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    //===========================[ Get String ]=================================
    new lsString[ 16 ];

    // GVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        GetGVarString( "TestGS", lsString, 16 );

    printf( "STRING: Get: GVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    // SVar
    liTick = GetTickCount( );

    for( new i = 0; i < ITERS; i ++ )
        GetSVarString( "TestGS", lsString, 16 );

    printf( "STRING: Get: SVar speed for %d iterations: %dms", ITERS, GetTickCount( ) - liTick );

    return 1;
}
Results:


So SVars are slower only at setting strings.
That's not entirely accurate. You're only allocating one element each time. I've only tested integers, but here's what I got by allocating 100,000 unique elements:

pawn Код:
new names[100000][16];
for (new i = 0; i < 100000; i++)
{
    format(names[i], sizeof(names[]), "name_%d", i);
}
pawn Код:
new time = GetTickCount();
for (new i = 0; i < 100000; i++)
{
    SetGVarInt(names[i], i);
}
printf("Time #1: %d", GetTickCount() - time);

time = GetTickCount();
for (new i = 0; i < 100000; i++)
{
    GetGVarInt(names[i]);
}
printf("Time #2: %d", GetTickCount() - time);
Код:
[19:03:10] Time #1: 54
[19:03:10] Time #2: 35
pawn Код:
new time = GetTickCount();
for (new i = 0; i < 100000; i++)
{
    SetSVarInt(names[i], i);
}
printf("Time #1: %d", GetTickCount() - time);
   
time = GetTickCount();
for (new i = 0; i < 100000; i++)
{
    GetSVarInt(names[i], i);
}
printf("Time #2: %d", GetTickCount() - time);
Код:
[19:04:05] Time #1: 1089
[19:04:06] Time #2: 1004
SVars are big improvement over properties, but they still seem to be slightly slower than GVars as they increase in number. I assume a hash table implementation wasn't used.

As for your suggestion: yes, I suppose that could be done pretty easily. JernejL also suggested iteration support to me a while back, but I haven't found the time to see about adding it yet.
Reply
#97

That's great!
Reply
#98

Quote:
Originally Posted by Incognito
Посмотреть сообщение
I've only tested integers, but here's what I got by allocating 100,000 unique elements:
Actually you can't create more than 2000 SVars.
There's no info about that on the wiki, but I've made this test:
pawn Код:
#include <a_samp>

main()
{
    static const svar_name_prefix[] = "svar";
    new svar_name[sizeof(svar_name_prefix) + 11];
    svar_name = svar_name_prefix;
    for (new i = 0; i < cellmax; ++i)
    {
        valstr(svar_name[4], i);
        new result = SetSVarInt(svar_name, i);
        printf("SVar: %s | Value: %d", svar_name, GetSVarInt(svar_name));
        if (0 == result)
        {
            printf("SVars limit: %d", i);
            break;
        }
    }
}
Output:
Код:
SVar: 0 | Value: 0
SVar: 1 | Value: 1
...
SVar: 1999 | Value: 1999
SVar: 2000 | Value: 0
SVars limit: 2000
Loop starts at 0 and at i = 2000 SetSVarInt returns 0 because it can't create more than 2000 SVars. GetSVarInt returns 0 as well because SVar "svar2000" was not created.
Reply
#99

I figured that might have been the case, as with PVars. It doesn't change the outcome of the results much, however.
Reply

at the moment, sa-mp have Gvar, what make yours and sa-mp different?
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)