Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.12.30;
Скачать: CL | DM;

Вниз

Насколько вызовы ф-ций тормозят работу программы?   Найти похожие ветки 

 
TStas ©   (2007-11-28 23:12) [0]

Есть программа, она, в главной своей части, переборы с очень большим числом итераций (миллиард - очень пристойное число). Чтобы она работала быстрее, я стараюсь заменить вызовы ф-ций их кодом. Понятно, что от такой замены код становится все менее и меннее читаемым.
А вопрос и есть сабж: насколько вызовы ф-ций тормозят работу программы?


 
wicked ©   (2007-11-28 23:18) [1]

в теории - замедляют, хоть и не намного - вызовы + создание и убийство фрейма стека
на практике - функции попадают в кеш процессора, отчего выполняются быстрее, чем раз-инлайненый код

так что надо смотреть в каждом отдельном случае - подготовить 2 версии кода - с вызовами ф-ций и инлайненым кодом, и сравнить
миллиард итераций - как раз хорошее число для проверки, когда незаметные задержки складутся в достаточно ощутимые интервалы


 
TStas ©   (2007-11-28 23:26) [2]

Подлежат встраиванию не ф-ции, а процедуры, притом без параметром и of object.


 
J_f_S   (2007-11-28 23:28) [3]


> wicked ©   (28.11.07 23:18) [1]

Ну. Инлайн всегда будет быстрей вызова функций. Кэш кэшем а затраты на call/push/pop/ret никто не отменял. К тому-же инлановые функции оставляют простор для оптимизации компиллятору, что в современных условиях очень важно.


 
J_f_S   (2007-11-28 23:29) [4]

При прочих равных, конечно (если нельзя улучшить алогоритм, уменьшить число вызовов и .т.д)


 
TStas ©   (2007-11-28 23:34) [5]

Сама процедура (она of object), подлежащая встраиванию, представляет из себя цикл с одной переменной и case с большим количеством ключей. Посто сейчас, пока код не отлажен, я не хочу встраивать, поскольку и так эта процедура уже больше 200 строк.


 
Узурап Мамуматкулович   (2007-11-28 23:42) [6]

>[3] J_f_S 28-Nov-2007, 23:28
>
>> wicked ©   (28.11.07 23:18) [1]
>
>Ну. Инлайн всегда будет быстрей вызова функций. Кэш кэшем
>а затраты на call/push/pop/ret никто не отменял. К тому-же
>инлановые функции оставляют простор для оптимизации
>компиллятору, что в современных условиях очень важно.

Это не затраты. Это копейки.

>[4] J_f_S 28-Nov-2007, 23:29
>При прочих равных, конечно (если нельзя улучшить алогоритм,
>уменьшить число вызовов и .т.д)

А вот в улучшении алгоритма стоит задуматься.
Для примера - icfp2007. Алгоритм был описан в описании контеста, но мало кто вовремя обратил внимание на последний абзац описания. Из-за этого все ломанулись реализовывать в лоб, не думая головой. А там для прогона все задачи требовалось ~20000000 и если следовать описанию активная работа со строками.


 
Узурап Мамуматкулович   (2007-11-28 23:44) [7]

*~20000000 итераций


 
J_f_S   (2007-11-28 23:51) [8]


> Узурап Мамуматкулович   (28.11.07 23:44) [7]

Я ж пишу - при прочих равных. Будем считать, что алгоритм непогрешим ;)

Теперь на затраты при вызове функций. Копейка - это копейка. Умножьте на миллиард. Ась?


 
Узурап Мамуматкулович   (2007-11-28 23:54) [9]

>[8] J_f_S 28-Nov-2007, 23:51
>
>> Узурап Мамуматкулович   (28.11.07 23:44) [7]
>
>Я ж пишу - при прочих равных. Будем считать, что алгоритм
>непогрешим ;)
>
>Теперь на затраты при вызове функций. Копейка - это
>копейка. Умножьте на миллиард. Ась?

пару push ... call и retn .. сколько машинных тактов потребуют? а частота процессоров сейчас какая?


 
Anatoly Podgoretsky ©   (2007-11-29 00:24) [10]

Задержка будет но она ничтожная, поскольку в функции 200 строк, другое дело если бы функция бьла короткой. Если соглашение о вызове обычное и количество параметров меньше трех, то затраты будут только на call/ret, а в самой функции свыше 1000 команд.


 
TStas ©   (2007-11-29 00:34) [11]

>Anatoly Podgoretsky То есть, не имеет смысла морочиться со встраиванием? Сама процедура - цикл с кейсами.


 
Anatoly Podgoretsky ©   (2007-11-29 00:37) [12]

Работать надо над алгоритмом, тогда можно выиграть не доли процента, а по существеннее.
Но ты бы привел для порядка хотя бы заголовок функции, а то разговор немого со слепым.


 
TStas ©   (2007-11-29 01:19) [13]

Алгоритм там - лучше не придумаешь. Точнее, как я его придумал, я эту программу и затеял под этот ОЧЕНЬ эффективный алгоритм. Просто, может, можно как-то еще быстрее сделать

procedure TDebuggerForm.Execute;
............
For I := 1 to n do
   begin
   ......
   OperRec := FOperList.Values[I]; //Получаю само действие
   // OperRec - это записать така вида что сделать и индексы где брать
  Case OperRec.Operation of //вот пошел Case
  //Operation - это поле записи перечислимого типа
  и в зависимости от него что-то делается с исходными данными,


 
TStas ©   (2007-11-29 01:21) [14]

Узнать я вот что хотел: это проценты или разы? Если процетны - даже и не буду морочиться, если разы, то дело нужное


 
KilkennyCat ©   (2007-11-29 01:27) [15]


> это проценты или разы?


а есть разница?


 
Celades ©   (2007-11-29 01:34) [16]


> Узнать я вот что хотел: это проценты или разы? Если процетны
> - даже и не буду морочиться, если разы, то дело нужное

пока не проверишь профилировщиком, оптимизировать что-то сверх меры глупо.


 
Slym ©   (2007-11-29 04:10) [17]

код приводи... может что в нем тормозит


 
@!!ex ©   (2007-11-29 09:12) [18]

> [13] TStas ©   (29.11.07 01:19)

Пишешь интрепретатор?
ТОгда ты ошибаешься. Есть более эффективный метод, нежели case.


 
Anatoly Podgoretsky ©   (2007-11-29 09:30) [19]

> TStas  (29.11.2007 00:34:11)  [11]

Если хочешь узнать точно, то измерь работу полной функции и с полностью замаскированым текстом, что бы остался только вызов.


 
TStas ©   (2007-11-29 11:35) [20]

Да не все так серьезно. Я просто спросил, что лучше. Если и правда в разы, то надо менять. Ладно, оставлю, как есть.


 
Anatoly Podgoretsky ©   (2007-11-29 11:53) [21]

> TStas  (29.11.2007 11:35:20)  [20]

Так упорствуем до конца.

Измерения не проводим,
код не сообщаем.


 
DiamondShark ©   (2007-11-29 14:34) [22]


> TStas ©   (29.11.07 01:19) [13]
> Алгоритм там - лучше не придумаешь. Точнее, как я его придумал,
>  я эту программу и затеял под этот ОЧЕНЬ эффективный алгоритм.

Офигительно не эффективный.


> procedure TDebuggerForm.Execute;
> ............
> For I := 1 to n do
>    begin
>    ......
>    OperRec := FOperList.Values[I]; //Получаю само действие
>    // OperRec - это записать така вида что сделать и индексы
> где брать

Что такое FOperList? Что такое Values? Это просто массив, или свойство?
Если OperRec -- это запись, то присваивание очень неэффективная операция. Очень много переписываний из памяти в память.


>   Case OperRec.Operation of //вот пошел Case
>   //Operation - это поле записи перечислимого типа
>   и в зависимости от него что-то делается с исходными данными,

Case -- кака.

Лучше сделать
TAbstractOper = class
public
 procedure Execute(); virtual; abstract;
end;

и для каждого типа сделать наследника.

тогда получится

For I := 1 to n do FOperList.Values[I].Execute();

Будет читабельно, расширябельно, поддерживабельно и нетормозабельно.

А затраты на вызов функции -- это действительно доли процента. Т.е. если цикл выполняется десять секунд, то накладные затраты -- это десятые доли секунды.
Стоит ли овчинка выделки?



Страницы: 1 вся ветка

Текущий архив: 2007.12.30;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.02 c
15-1196155571
limp
2007-11-27 12:26
2007.12.30
Стоимость разработки службы знакомств


6-1177336439
socket
2007-04-23 17:53
2007.12.30
TServerSocket and TClientSocket


15-1196342882
моряк
2007-11-29 16:28
2007.12.30
как стать нормальным программистом!


15-1196347111
Черный Шаман
2007-11-29 17:38
2007.12.30
Структурный вопрос - функции VS методы


2-1196766424
Цукор
2007-12-04 14:07
2007.12.30
TOpenDialog