Сейчас 12:45:02 Понедельник, 25 ноября, 2024 год
[ x ] Главная ⇒ Форум ⇐ RSS Файлы Cтатьи Картинки В о й т и   или   з а р е г и с т р и р о в а т ь с я


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: PUVer, SirNikolas, Ty3uK  
[Вопрос] Рекурсивные функции
FatalBladeДата: Четверг, 02 Февраля 2012, 20:47:56 | Сообщение # 1
10 уровень
Группа: Проверенные
Сообщений: 1523
Награды: 0
Репутация: 439
Блокировки:
Мне как то раз сказали что рекурсивные функции работают быстрее любых циклов для любых целей. Правда ли это? Может я и не правильно понял что значит рекурсия, но по моему вот это подходит под описание:

Code
function CheckRange takes unit u, unit un returns real
      if IsUnitInRange( un, u, 2000.0 ) then
        if IsUnitInRange( un, u, 1500.0 ) then
          if IsUnitInRange( un, u, 1000.0 ) then
            return 1.0
          endif
          return 0.8
        endif
       return 0.6
      else
       return 0.4
      endif
endfunction

Code
    set y = CheckRange( un, u )


Это кофицент награды золота за крипов. Чем дальше убитый вражеский юнит от вашего юнита, тем меньше кофицент. Тут правда есть конкретные значения, 1000, 1500, 2000.

Теперь вот вам отрывок кода, который выполняет то же самое, только по другому:

Code
              set dx = GetWidgetX(un) - GetWidgetX(u)
               set dy = GetWidgetY(un) - GetWidgetY(u)
               set d = SquareRoot( dx * dx + dy * dy )
               if d < 1000 then
                   set y = 1.00
               elseif d <= 1500 and d > 1000 then
                   set y = 0.80
               elseif d <= 2000 and d > 1500 then
                   set y = 0.60
               elseif d > 2000 then
                   set y = 0.40
               endif


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

P.S. Удалите плз похожую тему с раздела Вопросы по Картостроению.


 

DragoNДата: Четверг, 02 Февраля 2012, 21:44:37 | Сообщение # 2
Инквизитор
Группа: Стримеры
Сообщений: 4348
Награды: 7
Репутация: 2776
Блокировки:
использовать рекурсию считается как минимум нехорошим тоном в программировании

El Psy Congroo


Сообщение отредактировал DragoN - Четверг, 02 Февраля 2012, 21:45:08
 

FatalBladeДата: Четверг, 02 Февраля 2012, 22:02:31 | Сообщение # 3
10 уровень
Группа: Проверенные
Сообщений: 1523
Награды: 0
Репутация: 439
Блокировки:
Quote (DragoN)
использовать рекурсию считается как минимум нехорошим тоном в программировании

Ок. И всё же, в данном случае, какой вариант лучше для производительности их тех что я написал выше?


 

DragoNДата: Четверг, 02 Февраля 2012, 22:20:02 | Сообщение # 4
Инквизитор
Группа: Стримеры
Сообщений: 4348
Награды: 7
Репутация: 2776
Блокировки:
и кстати вот, что такое рекурсия
господин Ajaccio уже всё довольно понятно объяснил


El Psy Congroo
 

FatalBladeДата: Четверг, 02 Февраля 2012, 22:40:03 | Сообщение # 5
10 уровень
Группа: Проверенные
Сообщений: 1523
Награды: 0
Репутация: 439
Блокировки:
А вообще, как лучше проверять расстояние между юнитами для быстроты?

Code
IsUnitInRange( un, u, 2000.0 )

или
Code
              set dx = GetWidgetX(un) - GetWidgetX(u)
               set dy = GetWidgetY(un) - GetWidgetY(u)
               set d = SquareRoot( dx * dx + dy * dy )
               if d < 1000 then
                   set y = 1.00
               elseif d <= 1500 and d > 1000 then
                   set y = 0.80
               elseif d <= 2000 and d > 1500 then
                   set y = 0.60
               elseif d > 2000 then
                   set y = 0.40
               endif


 

ImpregnableДата: Пятница, 03 Февраля 2012, 04:33:53 | Сообщение # 6
6 уровень
Группа: Проверенные
Сообщений: 231
Награды: 0
Репутация: 92
Блокировки:
2 вариант будет быстрее, т.к IsUnitInRange это вызов функции, да еще и 3 раза, но при условии, что dx,dy и d - глобалки.

Вот немного подправленный код:
Code

     set dx = GetWidgetX(un) - GetWidgetX(u)
     set dy = GetWidgetY(un) - GetWidgetY(u)
     set d = SquareRoot( dx * dx + dy * dy )
     if d < 1000 then
         set y = 1.
     elseif d <= 1500
         set y = .8
     elseif d <= 2000
         set y = .6
     else
         set y = .4
     endif


З.Ы
И вообще, если хочешь повысить скорость, то elseif в циклах и часто вызываемых функциях лучше не использовать.
 

FatalBladeДата: Пятница, 03 Февраля 2012, 05:32:35 | Сообщение # 7
10 уровень
Группа: Проверенные
Сообщений: 1523
Награды: 0
Репутация: 439
Блокировки:
Quote (Impregnable)
И вообще, если хочешь повысить скорость, то elseif в циклах и часто вызываемых функциях лучше не использовать.

Значит вот так будет быстрее?
if ... then
...
endif
if ... then
...
endif
if ... then
....
endif


 

CancelДата: Пятница, 03 Февраля 2012, 05:58:45 | Сообщение # 8
8 уровень
Группа: Проверенные
Сообщений: 634
Награды: 0
Репутация: 158
Блокировки:
Quote (DragoN)
использовать рекурсию считается как минимум нехорошим тоном в программировании

почему это?
 

ImpregnableДата: Пятница, 03 Февраля 2012, 12:41:07 | Сообщение # 9
6 уровень
Группа: Проверенные
Сообщений: 231
Награды: 0
Репутация: 92
Блокировки:
Quote (FatalBlade)
Значит вот так будет быстрее?


Нет. Так будет намного хуже.

Ты не так понял... ну или я непонятно написал. Например, в данном случае использовать if'ы оптимальный вариант.
Да и не стоит беспокоиться о скорости пока не начнет лагать...
Единственное, что надо понимать - условия будут проверяться до тех пор, пока не будет какое-нибудь истинно или все не закончатся. Поэтому располагать их следует в порядке убывания, то есть на 1 месте то, которое будет чаще все истинно, на 2 не так часто и.т.д
 

  • Страница 1 из 1
  • 1
Поиск:

Copyright © 2006 - 2024 Warcraft3FT.info При копировании материалов c сайта ставьте, пожалуйста, активную обратную ссылку на нас • Design by gReeB04ki ©
Хостинг от uCoz