Property функции
#1

Речь идет о функциях set/get/delete/existproperty, которые могут создавать динамические переменные/данные. Также они могут создавать переменные, которые могут использовать все загруженные скрипты сервера. Созданные переменные могут изменяться/создаваться из любой функции и колбэка сервера.

Интересует скорость, функциональность, есть ли баги и лимиты. О том, как использовать я могу пояснить ниже, но скорость, баги и лимиты я не знаю. Возможно, это удобный инструмент, о котором мало кто знает и мало кто использует.

модер: посты сразу ниже - перенесены из другой темы
Reply
#2

обьяснений мне не нужно,сам не плохо понимаю как тут и что,дело в том что когда я около года назад пробовал изращаться с property то даже самое простое:
valstr(valuestr,"test string");
setproperty(0,"test",0,valuestr);
getproperty(0,"test",0,result);
strunpack(result,result);
print(result);
выдавало <null>
может я где был не прав?поправь тогда,а то я долго мозг долбал и пришлось тупо брать хеш строки и делать так:
valstr(valuestr,"test string");
setproperty(0,"",hash("test"),valuestr);
getproperty(0,"",hash("test"),result);
strunpack(result,result);
print(result);
в результате получая "test string" и теряя очень много времени на хеш
Reply
#3

Для использования property есть два четко разграниченных способа:
- чтобы хранить числовые значения, нужно в качестве имен использовать только строки
- чтобы хранить строковые значения, нужно в качестве имен использовать только числа (индексы)

Если этими правилами пренебречь, то сохранить любое значение не получиться. Т.е. "setproperty( 0, "test", 0, "test string" );" это неправильно, потому что тут попытка сохранить значение, где даны оба имени - строковое и числовое, а должно быть только одно - числовое.

Поясню на правильных примерах:

Code:
setproperty( 0, "cash", 123456 ); // создадим property cо строковым именем "cash" и числовым значением 123456
new money = getproperty( 0, "cash" ); // money = 123456


setproperty( _, _, 777, "test string" ); // создадим property c числовым именем 777 и строковым значением "test string"
setproperty( _, "", 777, "test string" ); // то же самое, что и выше
setproperty( 0, "", 777, "test string" ); // то же самое, что и выше

new testString[32];
getproperty( 0, _, 777, testString ); // testString = "test string"
Вопрос: как я для строковых значений использую строковые имена?
Ответ: я создаю для строкового значения свой property под нужным индексом, который сохраняю как числовое значение другого property со строковым именем. Вот такая вот связка.

Хочу разъяснить пару общих моментов:
- первый параметр во всех property функциях, это ИД абстрактной машины.
все фильтрскрипты и мод используют ИД = 0. Если хотите, чтобы созданные переменные были доступны
только из текущего скприпт и ниоткуда более, то используйте ИД > 0.
- Глобальный, скажем так, массив property это как обычный двумерный массив,
например array[1000][255] (тыща строк по 255 символов), но только динамический.
- Если в getproperty указать только строковое имя, то механизм поиска будет перебирать все строки массива по порядку,
пока не найдет указанное имя, после этого механизм вернет индекс массива в котором эта строка найдена.
- Если в getproperty указать только числовое имя (индекс), то механизм сразу вернет строку под указанным индексом в массиве,
т.е. этот способ быстрее

Показательный пример потенциальной ошибки:

Code:
setproperty( 0, _, 123456, "test string" ); // создадим property c числовым именем 123456 и строковым значением "test string"
setproperty( 0, "cash", 123456 ); // внимание, тут не создается новый property, а изменяется property, созданный выше

new testString[32];
getproperty( 0, _, 123456, testString ); // в testString будет "cash", а не "test string"
На данный момент это самое простое и общее объяснение механизма property.
Reply
#4

Quote:
Originally Posted by MX_Master
Для использования property есть два четко разграниченных способа:
- чтобы хранить числовые значения, нужно в качестве имен использовать только строки
- чтобы хранить строковые значения, нужно в качестве имен использовать только числа (индексы)
этого не знал большое спасибо тебе
Reply
#5

Кто-нибудь проверял скорость создания/правки property? И есть ли лимиты по длине строковых значений / массивов ?

Подумываю перевести новый INI inc на динамические переменные.

Создал вот такой ФС для проверки скоростей копирования строк и правки/создания property. До 1000 слотов строковых property создаются/меняются за приемлемое время, в районе 3-4 мсек (на моем компе). После 1000 слотов время правки/создания увеличивается в прогрессии. Т.е. при 10 тыщ слотах правка/чтение/создание выполняется за примерно одинаковые 3500 мсек (3,5 сек) ^^

Code:
#include <a_samp>

#define MAX_COUNT    1000
#define TEST_STR    "012345678901234567890123456789"
#define NEW_TEST_STR  "0000000000000000000000000000000"

stock strcopy ( dest[], source[], maxsize = sizeof(dest) )
{
  new p;

  for ( ; source[p] != 0 && p < maxsize; p++ ) dest[p] = source[p];

  dest[ min( p, maxsize - 1 ) ] = 0;
}

public OnFilterScriptInit()
{
  new str[32], time, i;



  print("\n");
  print( "string functions test (" #MAX_COUNT " iterations)" );

  print( " 1. copy" );

  time = GetTickCount();
  for ( i = 0, str[0] = 0; i < MAX_COUNT; i++ ) strmid( str, TEST_STR, 0, 30 );
  time = GetTickCount() - time;
  printf( " * strmid: %d msec, str(%d) = `%s`", time, strlen(str), str );

  time = GetTickCount();
  for ( i = 0, str[0] = 0; i < MAX_COUNT; i++ ) { memcpy( str, TEST_STR, 0, 120 ); str[30] = 0; }
  time = GetTickCount() - time;
  printf( " * memcpy: %d msec, str(%d) = `%s`", time, strlen(str), str );

  time = GetTickCount();
  for ( i = 0, str[0] = 0; i < MAX_COUNT; i++ ) strcopy( str, TEST_STR );
  time = GetTickCount() - time;
  printf( " * strcopy: %d msec, str(%d) = `%s`", time, strlen(str), str );



  print("\n");
  print( "property test (" #MAX_COUNT " slots)" );

  print( " 1. create" );
  time = GetTickCount();
  for ( i = 0; i < MAX_COUNT; i++ ) setproperty( 0, _, i, TEST_STR );
  time = GetTickCount() - time;
  printf( " * setproperty: %d msec", time );

  print( " 2. get 1" );
  time = GetTickCount();
  for ( i = 0, str[0] = 0; i < MAX_COUNT; i++ ) { getproperty( 0, _, i, str ); strunpack(str,str); }
  time = GetTickCount() - time;
  printf( " * getproperty: %d msec, str(%d) = `%s`", time, strlen(str), str );

  print( " 3. edit" );
  time = GetTickCount();
  for ( i = 0; i < MAX_COUNT; i++ ) setproperty( 0, _, i, NEW_TEST_STR );
  time = GetTickCount() - time;
  printf( " * setproperty: %d msec", time );

  print( " 4. get 2" );
  time = GetTickCount();
  for ( i = 0, str[0] = 0; i < MAX_COUNT; i++ ) { getproperty( 0, _, i, str ); strunpack(str,str); }
  time = GetTickCount() - time;
  printf( " * getproperty: %d msec, str(%d) = `%s`", time, strlen(str), str );

  print( " 5. delete" );
  time = GetTickCount();
  for ( i = 0; i < MAX_COUNT; i++ ) deleteproperty( 0, _, i );
  time = GetTickCount() - time;
  printf( " * deleteproperty: %d msec", time );
}
- Копирование строк стандартными функциями strmid/memcpy выполняется примерно за 1 мсек при 1000 итераций,
и за 4 мсек при 10 тыщ итерациях.

- Самописная Pawn функция по копированию строк при 1000 итерациях выполняется за 23 мсек,
а при 1000 итерациях за 111 мсек.
Reply
#6

Основываясь на просмотре исходников и моем их понимании:

1) Проперти организованы в виде линейного связного списка (подробности тут), каждый из элементов которого содержит имя (строка символов) и значение (целое число). Еще есть третий параметр, в документации называемый id абстрактной машины - придуман для того, чтобы можно было иметь несколько элементов с одинаковыми именами либо значениями и различать их при поиске; он не накладывает никаких ограничений и не отсеивает разные скрипты по возможности доступа к элементам и может принимать вообще любое значение, хоть 100500.

2) Из первого пункта следует, что время доступа к пропертям прежде всего зависит от их количества - чем больше, тем дольше (тесты сверху тому подтверждение). Поэтому лучше по ненадобности удалять более неиспользуемые элементы. Еще стоит отметить, что любая операция, будь то поиск (getproperty), вставка (setproperty) или удаление (deleteproperty) элемента, по имени производится существенно медленне, нежели по значению (строки сравниваются дольше чисел).

3) Насчет лимитов... по-моему есть только один - количество доступной памяти, больше элементов - больше нужно памяти, кроме того ее расходование зависит и от размеров имен хранящихся элементов.

Короче, заключение: штука, безусловно, полезная, но для интенсивного использования и больших объемов данных не очень подходит... таков мой субъективный вердикт

PS: весь код пропертей находится в /axm/amxcore.c
Reply
#7

уже начал переделку нового INI двига под Property,
проблема с увеличением размера АМХ за счет глобальных массивов - должна исчезнуть
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)