SA-MP Forums

Go Back   SA-MP Forums > Non-English > Languages > Русский/Russian

Reply
 
Thread Tools Display Modes
Old 13/02/2017, 01:51 AM   #1
Diman777
Huge Clucker
 
Diman777's Avatar
 
Join Date: Aug 2011
Location: Ростов-на-Дону
Posts: 430
Reputation: 22
Default Написание плагинов

Многие пишут, что через плагин всё быстрее работает (с условием если грамотно и со смыслом их писать).
Решил попробывать написать свой 1-ый плагин, в котором пока что есть 1 функция UpperToLower, она переводит строку в нижний регистр.
Результат тестирования скорости поражает.

код C++:
PHP Code:
// native UpperToLower(string[]);
static cell AMX_NATIVE_CALL UpperToLower(AMX *amxcell *params)
{
    
char *string;
    
int len 0;
    
amx_StrParam(amxparams[1], string);
    if (
string != NULL)
    {
        
len strlen(string);
        for (
int i 0leni++)
        {
            switch (
string[i])
            {
                case 
'A'string[i] = 'a'; break;
                case 
'B'string[i] = 'b'; break;
                case 
'C'string[i] = 'c'; break;
                case 
'D'string[i] = 'd'; break;
                case 
'E'string[i] = 'e'; break;
                case 
'F'string[i] = 'f'; break;
                case 
'G'string[i] = 'g'; break;
                case 
'H'string[i] = 'h'; break;
                case 
'I'string[i] = 'i'; break;
                case 
'J'string[i] = 'j'; break;
                case 
'K'string[i] = 'k'; break;
                case 
'L'string[i] = 'l'; break;
                case 
'M'string[i] = 'm'; break;
                case 
'N'string[i] = 'n'; break;
                case 
'O'string[i] = 'o'; break;
                case 
'P'string[i] = 'p'; break;
                case 
'Q'string[i] = 'q'; break;
                case 
'R'string[i] = 'r'; break;
                case 
'S'string[i] = 's'; break;
                case 
'T'string[i] = 't'; break;
                case 
'U'string[i] = 'u'; break;
                case 
'V'string[i] = 'v'; break;
                case 
'W'string[i] = 'w'; break;
                case 
'X'string[i] = 'x'; break;
                case 
'Y'string[i] = 'y'; break;
                case 
'Z'string[i] = 'z'; break;
                case 
'А'string[i] = 'а'; break;
                case 
'Б'string[i] = 'б'; break;
                case 
'В'string[i] = 'в'; break;
                case 
'Г'string[i] = 'г'; break;
                case 
'Д'string[i] = 'д'; break;
                case 
'Е'string[i] = 'е'; break;
                case 
'Ё'string[i] = 'ё'; break;
                case 
'Ж'string[i] = 'ж'; break;
                case 
'З'string[i] = 'з'; break;
                case 
'И'string[i] = 'и'; break;
                case 
'Й'string[i] = 'й'; break;
                case 
'К'string[i] = 'к'; break;
                case 
'Л'string[i] = 'л'; break;
                case 
'М'string[i] = 'м'; break;
                case 
'Н'string[i] = 'н'; break;
                case 
'О'string[i] = 'о'; break;
                case 
'П'string[i] = 'п'; break;
                case 
'Р'string[i] = 'р'; break;
                case 
'С'string[i] = 'с'; break;
                case 
'Т'string[i] = 'т'; break;
                case 
'У'string[i] = 'у'; break;
                case 
'Ф'string[i] = 'ф'; break;
                case 
'Х'string[i] = 'х'; break;
                case 
'Ц'string[i] = 'ц'; break;
                case 
'Ч'string[i] = 'ч'; break;
                case 
'Ш'string[i] = 'ш'; break;
                case 
'Щ'string[i] = 'щ'; break;
                case 
'Ъ'string[i] = 'ъ'; break;
                case 
'Ы'string[i] = 'ы'; break;
                case 
'Ь'string[i] = 'ь'; break;
                case 
'Э'string[i] = 'э'; break;
                case 
'Ю'string[i] = 'ю'; break;
                case 
'Я'string[i] = 'я'; break;
            }
        }
        
string[len] = '\0';
    }
    else
    {
        
string "";
    }
    
cell *addr NULL;
    
amx_GetAddr(amxparams[1], &addr);
    
amx_SetString(addrstring00len+1);
    return 
1;

код Pawn:
PHP Code:
UpperToLower(string[])
{
    new 
len strlen(string);
    for (new 
ileni++)
    {
        switch (
string[i])
        {
            case 
'A'string[i] = 'a';
            case 
'B'string[i] = 'b';
            case 
'C'string[i] = 'c';
            case 
'D'string[i] = 'd';
            case 
'E'string[i] = 'e';
            case 
'F'string[i] = 'f';
            case 
'G'string[i] = 'g';
            case 
'H'string[i] = 'h';
            case 
'I'string[i] = 'i';
            case 
'J'string[i] = 'j';
            case 
'K'string[i] = 'k';
            case 
'L'string[i] = 'l';
            case 
'M'string[i] = 'm';
            case 
'N'string[i] = 'n';
            case 
'O'string[i] = 'o';
            case 
'P'string[i] = 'p';
            case 
'Q'string[i] = 'q';
            case 
'R'string[i] = 'r';
            case 
'S'string[i] = 's';
            case 
'T'string[i] = 't';
            case 
'U'string[i] = 'u';
            case 
'V'string[i] = 'v';
            case 
'W'string[i] = 'w';
            case 
'X'string[i] = 'x';
            case 
'Y'string[i] = 'y';
            case 
'Z'string[i] = 'z';
            case 
'А'string[i] = 'а';
            case 
'Б'string[i] = 'б';
            case 
'В'string[i] = 'в';
            case 
'Г'string[i] = 'г';
            case 
'Д'string[i] = 'д';
            case 
'Е'string[i] = 'е';
            case 
'Ё'string[i] = 'ё';
            case 
'Ж'string[i] = 'ж';
            case 
'З'string[i] = 'з';
            case 
'И'string[i] = 'и';
            case 
'Й'string[i] = 'й';
            case 
'К'string[i] = 'к';
            case 
'Л'string[i] = 'л';
            case 
'М'string[i] = 'м';
            case 
'Н'string[i] = 'н';
            case 
'О'string[i] = 'о';
            case 
'П'string[i] = 'п';
            case 
'Р'string[i] = 'р';
            case 
'С'string[i] = 'с';
            case 
'Т'string[i] = 'т';
            case 
'У'string[i] = 'у';
            case 
'Ф'string[i] = 'ф';
            case 
'Х'string[i] = 'х';
            case 
'Ц'string[i] = 'ц';
            case 
'Ч'string[i] = 'ч';
            case 
'Ш'string[i] = 'ш';
            case 
'Щ'string[i] = 'щ';
            case 
'Ъ'string[i] = 'ъ';
            case 
'Ы'string[i] = 'ы';
            case 
'Ь'string[i] = 'ь';
            case 
'Э'string[i] = 'э';
            case 
'Ю'string[i] = 'ю';
            case 
'Я'string[i] = 'я';
        }
    }

код для теста:
PHP Code:
public OnGameModeInit()
{
    new 
time GetTickCount();
    for (new 
i1000000i++)
    {
        
UpperToLower("текст");
    }
    
printf("результат: %d ms"GetTickCount() - time);
    return 
1;

Результат тестирования UpperToLower:

без jit:
C++ | короткая строка = 172, длинная строка = 1047
Pawn | короткая строка = 1978, длинная строка = 8934

с jit:
C++ | короткая строка = 162, длинная строка = 1028
Pawn | короткая строка = 264, длинная строка = 1672

строки, которые использовались при тесте:
Code:
20 символов - иЛBё[еЬMDХ+T9wX/p1%Жs
100 символов - Юc№,Q)CxТФLrнПкХBjф[oiCЧм<bhшЗ,ыWR]ЁxчM}*Д8аCbР+bэjЭ1№D=оnнM!чepWo%GTKЧyR6VTЙSАщэЭSemюjFOЩ]ЭьтЛНЖ.ЧHLЛ

Процессор, на котором происходило тестирование: Intel Core i3 530 @ 2.93GHz

Скачать сборку для тестов v0.0.3 (мод + исходники)

Почему через плагин функции работают быстрее? Каковы преимущества?

Last edited by Diman777; 20/02/2017 at 02:51 PM. Reason: почищена сборка; инфа о процессоре
Diman777 is offline   Reply With Quote
Old 13/02/2017, 08:29 AM   #2
White_116
High-roller
 
Join Date: Sep 2010
Location: Russia/116
Posts: 1,447
Reputation: 65
Default Re: Написание плагинов

http://forum.sa-mp.com/showpost.php?...4&postcount=27 подключи jit compiler и проверь ещё разок.
__________________
White_116 is offline   Reply With Quote
Old 13/02/2017, 09:09 AM   #3
DartfoL
Gangsta
 
DartfoL's Avatar
 
Join Date: Apr 2012
Posts: 732
Reputation: 28
Default Re: Написание плагинов

Quote:
Почему через плагин функции работают быстрее? Каковы преимущества?
потому что павн компилируется в байт код и инструкции выполняет AMX машина, а плагины компилируется в машинный код и он сразу напрямую исполняется процессором

P.S. 666-й пост
__________________
DartfoL is offline   Reply With Quote
Old 13/02/2017, 09:36 AM   #4
OstGot
Gangsta
 
OstGot's Avatar
 
Join Date: Mar 2013
Location: Gomel, Belarus
Posts: 567
Reputation: 235
Default Re: Написание плагинов

Дополню. Pawn компилятор слаб в оптимизациях, чего о C++ компиляторах сказать нельзя
__________________
aka Nexius
Don't want to always check for updates of my scripts?
Include it the last, after all others
Nexius's Update Checker
OstGot is offline   Reply With Quote
Old 13/02/2017, 10:21 AM   #5
DartfoL
Gangsta
 
DartfoL's Avatar
 
Join Date: Apr 2012
Posts: 732
Reputation: 28
Default Re: Написание плагинов

сейчас ещё раз глянул тему и нашёл ошибку в павн коде: strlen вызывается при каждой итерации, что существенно замедляет работу

И да, почему на плюсах используется switch-case, а на павне арифметика?
__________________
DartfoL is offline   Reply With Quote
Old 13/02/2017, 10:31 AM   #6
Mutha_X
Gangsta
 
Join Date: Sep 2009
Location: recursion
Posts: 621
Reputation: 24
Default Re: Написание плагинов

Можно в принципе было и через таблицы соответствия написать (и там и там; т.е. безусловную реализацию), тогда и наглядность по скорости работы с памятью повысилась.
__________________
Russian forums: asking question - taking grammar notations.
Учитесь задавать вопросы по существу и изучать матчасть: иначе приобретайте лекарство "НИБОМБИН".
Mutha_X is offline   Reply With Quote
Old 13/02/2017, 01:45 PM   #7
Diman777
Huge Clucker
 
Diman777's Avatar
 
Join Date: Aug 2011
Location: Ростов-на-Дону
Posts: 430
Reputation: 22
Default Re: Написание плагинов

Переделал, см. 1-ый пост.
С jit действительно функция от Pawn выполнилась быстрее, это забавно наблюдать)
Diman777 is offline   Reply With Quote
Old 13/02/2017, 03:37 PM   #8
Mutha_X
Gangsta
 
Join Date: Sep 2009
Location: recursion
Posts: 621
Reputation: 24
Default Re: Написание плагинов

Автор, предлагаю тему в формат статьи переделать (+ в репу будет ) и добавить вот что:
* сравнение производительности твоего кода для длинной строки (с jit и без) (можно взять ipsum lorem бла бла бла...) и для короткой (уже ты сделал);
* Всё тоже самое, но немного для другой реализации (смотри ниже код);
* Указать на каком процессоре и на какой системе получены результаты (я наблюдал ощутимую разницу в производительности аналогичных между собой решений на павне в зависимости от архитектуры проца);
Code:
// PAWN
new chars_lower_ascii[] = // en+ru
{
	0x00010203,0x04050607,0x08090A0B,0x0C0D0E0F,0x10111213,0x14151617,0x18191A1B,0x1C1D1E1F,
	0x20212223,0x24252627,0x28292A2B,0x2C2D2E2F,0x30313233,0x34353637,0x38393A3B,0x3C3D3E3F,
	0x40616263,0x64656667,0x68696A6B,0x6C6D6E6F,0x70717273,0x74757677,0x78797A5B,0x5C5D5E5F,
	0x60616263,0x64656667,0x68696A6B,0x6C6D6E6F,0x70717273,0x74757677,0x78797A7B,0x7C7D7E7F,
	0x80818283,0x84858687,0x88898A8B,0x8C8D8E8F,0x90919293,0x94959697,0x98999A9B,0x9C9D9E9F,
	0xA0A1A2A3,0xA4A5A6A7,0xB8A9AAAB,0xACADAEAF,0xB0B1B2B3,0xB4B5B6B7,0xB8B9BABB,0xBCBDBEBF,
	0xE0E1E2E3,0xE4E5E6E7,0xE8E9EAEB,0xECEDEEEF,0xF0F1F2F3,0xF4F5F6F7,0xF8F9FAFB,0xFCFDFEFF,
	0xE0E1E2E3,0xE4E5E6E7,0xE8E9EAEB,0xECEDEEEF,0xF0F1F2F3,0xF4F5F6F7,0xF8F9FAFB,0xFCFDFEFF
};
stock StringToLowerByTable_ASCII(string[]) {
	new index = -1;
	while(string[++index]) {
			string[index] = chars_lower_ascii{string[index]};

	}
}
// C/C++
char unsigned chars_lower_ascii[] = {
	0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
	0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
	0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
	0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
	0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
	0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x5B,0x5C,0x5D,0x5E,0x5F,
	0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
	0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
	0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
	0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
	0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xB8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
	0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
	0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
	0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
	0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
	0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
};
void StringToLowerByTable_ASCII(string[]) {
	int index = -1;
	while(string[++index]) {
		string[index] = chars_lower_ascii[string[index]];
	}
}
__________________
Russian forums: asking question - taking grammar notations.
Учитесь задавать вопросы по существу и изучать матчасть: иначе приобретайте лекарство "НИБОМБИН".
Mutha_X is offline   Reply With Quote
Old 13/02/2017, 03:47 PM   #9
White_116
High-roller
 
Join Date: Sep 2010
Location: Russia/116
Posts: 1,447
Reputation: 65
Default Re: Написание плагинов

Quote:
Originally Posted by Mutha_X View Post
Автор, предлагаю тему в формат статьи переделать (+ в репу будет ) и добавить вот что:
* сравнение производительности твоего кода для длинной строки (с jit и без) (можно взять ipsum lorem бла бла бла...) и для короткой (уже ты сделал);
* Всё тоже самое, но немного для другой реализации (смотри ниже код);
* Указать на каком процессоре и на какой системе получены результаты (я наблюдал ощутимую разницу в производительности аналогичных между собой решений на павне в зависимости от архитектуры проца);
Code:
// PAWN
new chars_lower_ascii[] = // en+ru
{
	0x00010203,0x04050607,0x08090A0B,0x0C0D0E0F,0x10111213,0x14151617,0x18191A1B,0x1C1D1E1F,
	0x20212223,0x24252627,0x28292A2B,0x2C2D2E2F,0x30313233,0x34353637,0x38393A3B,0x3C3D3E3F,
	0x40616263,0x64656667,0x68696A6B,0x6C6D6E6F,0x70717273,0x74757677,0x78797A5B,0x5C5D5E5F,
	0x60616263,0x64656667,0x68696A6B,0x6C6D6E6F,0x70717273,0x74757677,0x78797A7B,0x7C7D7E7F,
	0x80818283,0x84858687,0x88898A8B,0x8C8D8E8F,0x90919293,0x94959697,0x98999A9B,0x9C9D9E9F,
	0xA0A1A2A3,0xA4A5A6A7,0xB8A9AAAB,0xACADAEAF,0xB0B1B2B3,0xB4B5B6B7,0xB8B9BABB,0xBCBDBEBF,
	0xE0E1E2E3,0xE4E5E6E7,0xE8E9EAEB,0xECEDEEEF,0xF0F1F2F3,0xF4F5F6F7,0xF8F9FAFB,0xFCFDFEFF,
	0xE0E1E2E3,0xE4E5E6E7,0xE8E9EAEB,0xECEDEEEF,0xF0F1F2F3,0xF4F5F6F7,0xF8F9FAFB,0xFCFDFEFF
};
stock StringToLowerByTable_ASCII(string[]) {
	new index = -1;
	while(string[++index]) {
			string[index] = chars_lower_ascii{string[index]};

	}
}
// C/C++
char unsigned chars_lower_ascii[] = {
	0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
	0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
	0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
	0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
	0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
	0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x5B,0x5C,0x5D,0x5E,0x5F,
	0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
	0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
	0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
	0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
	0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xB8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
	0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
	0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
	0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
	0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
	0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
};
void StringToLowerByTable_ASCII(string[]) {
	int index = -1;
	while(string[++index]) {
		string[index] = chars_lower_ascii[string[index]];
	}
}
Е*ать ты велосипедист. кинул же решение в первом сообщении.

http://forum.sa-mp.com/showpost.php?...4&postcount=27
__________________
White_116 is offline   Reply With Quote
Old 13/02/2017, 04:53 PM   #10
Mutha_X
Gangsta
 
Join Date: Sep 2009
Location: recursion
Posts: 621
Reputation: 24
Default Re: Написание плагинов

Quote:
Originally Posted by White_116 View Post
Е*ать ты велосипедист. кинул же решение в первом сообщении.

http://forum.sa-mp.com/showpost.php?...4&postcount=27
Строго говоря, пока ты условия применения не уточнил - это не велосипед вовсе... это моноцикл :
отличие лишь в способе проверки условия окончания цикла и strlen только у тебя.
Из этого вытекает, что примерно до 16 (а это могут быть названия вещей и ники игроков) включительно символов с символом-терминатором будет выигрывать мой способ (тестировал без jit), а у тебя выгодный алгоритм для длинных строк (например запросы в бд (хз зачем), антикапс и другое).

На твоём бы месте я бы написал вышеизложенное и средство, которое на этапе компиляции выбирало бы оптимальный вариант (функцию) на основе размера целевого массива.

И да, автор не менял свой алгоритм на твой после предложения и указал цифры только для своего...
__________________
Russian forums: asking question - taking grammar notations.
Учитесь задавать вопросы по существу и изучать матчасть: иначе приобретайте лекарство "НИБОМБИН".
Mutha_X is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Разработка плагинов - как достать адресс функции? therainycat Русский/Russian 6 18/09/2013 08:45 PM


All times are GMT. The time now is 03:30 PM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.