PDA

Просмотр полной версии : [Вопрос] Цикл for



Son of the Moon
03.09.2016, 21:37
Доброе время суток.
Где-то слышал о том что цикл for работает быстрее если:


#define MAX_AMOUNT 25
for(new i = MAX_AMOUNT; i > 0; i--)
{
}


Нежели так:


#define MAX_AMOUNT 25
for(new i; i < MAX_AMOUNT; i++)
{
}


Так ли это? если же да, почему так получается?

Sp1ke
03.09.2016, 21:49
Доброе время суток.
Где-то слышал о том что цикл for работает быстрее если:


#define MAX_AMOUNT 25
for(new i = MAX_AMOUNT; i > 0; i--)
{
}


Нежели так:


#define MAX_AMOUNT 25
for(new i; i < MAX_AMOUNT; i++)
{
}


Так ли это? если же да, почему так получается?
Изменю под вариант от DC...
Тесты проводились на http://imgur.com/a/MFA6S

$continue$
03.09.2016, 22:09
Вообще то цикл на оборот быстрей из пару инструкции в ASM

Daniel_Cortez
03.09.2016, 22:28
Доброе время суток.
Где-то слышал о том что цикл for работает быстрее если:


#define MAX_AMOUNT 25
for(new i = MAX_AMOUNT; i > 0; i--)
{
}


Нежели так:


#define MAX_AMOUNT 25
for(new i; i < MAX_AMOUNT; i++)
{
}


Так ли это? если же да, почему так получается?
Во-первых, у этих циклов два разных диапазона. Если во втором цикле счётчик принимает диапазон значений от 0 до MAX_AMOUNT-1, то в первом - от MAX_AMOUNT до 1.
Исправленный вариант обратного цикла будет выглядеть так:


for (new i = MAX_AMOUNT; i-- != 0; )
{
}

Во-вторых, у обратного цикла есть потенциал выполняться быстрее за счёт сравнения с нулём в условии выхода: вместо двух инструкций AMX (eq, jzer/jnz) будет использоваться только одна (jzer/jnz). Впрочем, на практике это принесёт пользу лишь в самом критичном ко времени выполнения коде - строковых функциях, часто вызываемых коллбэках типа OnPlayerUpdate, etc.

ziggi
04.09.2016, 02:35
Если нужна максимальная производительность, то циклы лучше вообще не использовать, а продублировать код нужное количество раз (это не шутка).

Вы совсем не там ищете оптимизацию, оптимизируйте свои алгоритмы. Это не Pawn медленный, это просто вы не умеете им пользоваться. Более того, пытаясь "оптимизировать" языковые конструкции подобным образом, вы ухудшаете читабельность кода, что усложнит его модификацию и увеличит вероятность появления ошибки. Оно вам надо? Лучше уберите тысячу проверок с IsPlayerInRangeOfPoint для ваших домов, это даст реально существенный результат (видел много примеров, почти у всех так).

Son of the Moon
05.09.2016, 17:11
Если нужна максимальная производительность, то циклы лучше вообще не использовать, а продублировать код нужное количество раз (это не шутка).

Вы совсем не там ищете оптимизацию, оптимизируйте свои алгоритмы. Это не Pawn медленный, это просто вы не умеете им пользоваться. Более того, пытаясь "оптимизировать" языковые конструкции подобным образом, вы ухудшаете читабельность кода, что усложнит его модификацию и увеличит вероятность появления ошибки. Оно вам надо? Лучше уберите тысячу проверок с IsPlayerInRangeOfPoint для ваших домов, это даст реально существенный результат (видел много примеров, почти у всех так).

ты хочешь сказать что если к примеру я использую на сервере 1000 домов, на каждый писать загрузку?

- - - Добавлено - - -

Кстати что на счет этого кода?
Пример:


new counter;

public OnGameModeInit()
{
Loading();
return true;
}

stock Loading()
{
if(counter < 10)
{
test[counter] = 1;
counter++;
Loading();

}
return true;
}

Redsan
05.09.2016, 17:25
ты хочешь сказать что если к примеру я использую на сервере 1000 домов, на каждый писать загрузку?

- - - Добавлено - - -

Кстати что на счет этого кода?
Пример:


new counter;

public OnGameModeInit()
{
Loading();
return true;
}

stock Loading()
{
if(counter < 10)
{
test[counter] = 1;
counter++;
Loading();

}
return true;
}


Рекурсивная функция.

ziggi
05.09.2016, 17:53
ты хочешь сказать что если к примеру я использую на сервере 1000 домов, на каждый писать загрузку?
Нет, я хочу сказать именно то, что я там написал.



Кстати что на счет этого кода?
Пример:


new counter;

public OnGameModeInit()
{
Loading();
return true;
}

stock Loading()
{
if(counter < 10)
{
test[counter] = 1;
counter++;
Loading();

}
return true;
}


Не вижу ни одной причины использовать здесь рекурсивный вызов функции.

new counter;

public OnGameModeInit()
{
Loading();
return true;
}

stock Loading()
{
while (counter < 10)
{
test[counter] = 1;
counter++;
}
return true;
}

Son of the Moon
05.09.2016, 19:02
Нет, я хочу сказать именно то, что я там написал.



Не вижу ни одной причины использовать здесь рекурсивный вызов функции.

new counter;

public OnGameModeInit()
{
Loading();
return true;
}

stock Loading()
{
while (counter < 10)
{
test[counter] = 1;
counter++;
}
return true;
}

ну ты же написал что лучше вообще не использовать циклы, while же цикл, тогда как по другому?

ziggi
05.09.2016, 19:12
ну ты же написал что лучше вообще не использовать циклы, while же цикл, тогда как по другому?

Я написал: "продублировать код нужное количество раз", где тут хоть слово о рекурсии? И рекурсия медленнее циклов (по крайней мере в Pawn).


new counter;

public OnGameModeInit()
{
Loading();
return true;
}

stock Loading()
{
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
return true;
}
Да, это быстрее циклов. Но разумно ли так писать код?

DeimoS
05.09.2016, 19:19
Китайский код конфирмед (http://lurkmore.to/_/1806#mws_6F75v7+)

Son of the Moon
05.09.2016, 20:59
Я написал: "продублировать код нужное количество раз", где тут хоть слово о рекурсии? И рекурсия медленнее циклов (по крайней мере в Pawn).


new counter;

public OnGameModeInit()
{
Loading();
return true;
}

stock Loading()
{
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
test[counter] = 1;
counter++;
return true;
}
Да, это быстрее циклов. Но разумно ли так писать код?

Вот за это я у тебя и спросил, дело в том что вот при загрузке 500+ что я буду дублировать код?

ziggi
05.09.2016, 21:10
Вот за это я у тебя и спросил, дело в том что вот при загрузке 500+ что я буду дублировать код?

Если ты хочешь добиться максимальной производительности, то да (хотя, наверное, этот код можно ещё больше ускорить с помощью emit).

P.S. Ты действительно не понимаешь, что я хочу донести? :)

Nexius_Tailer
05.09.2016, 21:11
Вот за это я у тебя и спросил, дело в том что вот при загрузке 500+ что я буду дублировать код?
Ну так написано выше: "если нужна максимальная производительность". Это ведь не говорит о том, что такой максимально производительный код будет вообще читабельным. Совет: пока ты не видишь реальной нужды что-то улучшать/делать более производительным, а тем более если не понимаешь до конца, как это улучит твой код - не морочь себе голову, это реально для тебя никак не окупится.

Son of the Moon
05.09.2016, 22:03
Если ты хочешь добиться максимальной производительности, то да (хотя, наверное, этот код можно ещё больше ускорить с помощью emit).

P.S. Ты действительно не понимаешь, что я хочу донести? :)

я понял это, ну ты написал за то что не нужно его использовать а сам while поставил :D

Nexius_Tailer
05.09.2016, 22:40
я понял это, ну ты написал за то что не нужно его использовать а сам while поставил :D
Если бы его было не нужно использовать, его бы не реализовывали.

vovandolg
05.09.2016, 23:06
(хотя, наверное, этот код можно ещё больше ускорить с помощью emit).

Можно пример?)

DeimoS
06.09.2016, 01:33
Ну так написано выше: "если нужна максимальная производительность". Это ведь не говорит о том, что такой максимально производительный код будет вообще читабельным.

Вопрос даже не в читабельности, а в том, велика ли будет разница между "максимальной" производительностью и "обычной". В SA-MP ситуации, когда пригодится "максимальная" производительность, можно пересчитать по пальцам. Да и то, даже без этой "максимальной" производительности, потери будут минимальны.



Можно пример?)

Примеров может быть множество. Тут просто нужно понимать принципы работы памяти и уметь играться с #emit (информация есть в ванильном гайде (https://raw.githubusercontent.com/compuphase/pawn/66e67291326b193045e52e4d6bcb51663260d6c3/doc/pawn-imp.pdf) к языку Pawn).
Ну вот (http://pro-pawn.ru/showthread.php?10231-cc-%28ZCMD-DC_CMD%29) один из примеров баловства с #emit. Хоть и не совсем подходит к вопросу автора, но там показано то, как #emit в умелых руках может ускорить код

ziggi
06.09.2016, 08:54
я понял это, ну ты написал за то что не нужно его использовать а сам while поставил :D

Потому что меня устраивает производительность циклов. И для меня читабельность и красота кода гораздо важнее его производительности.

vovandolg
06.09.2016, 14:09
Потому что меня устраивает производительность циклов. И для меня читабельность и красота кода гораздо важнее его производительности.

Щас бы Seregamil тебя расстрелял за такие слова:lol: