@Algoritmus-net

Как Ускорить выполнение функции вызвоной по укозателю?

Если в цикле складывать два числа миллиард раз это займёт 2555 мс. Если в цикле вызывать миллиард раз функцию по указателю в которой складываются теже два числа это займёт 28345 мс. Почему такая разница во времени, больше чем в 10 раз. Перемменные в процедуру не передаются.

#include <stdio.h>
#include "stdafx.h"
#include <ctime> 
#include <conio.h>
int z = 1;
void add()
{
	z = 1 + 1;
}

int main(void)
{
	void(*operations[1])() = { add };
	
	unsigned int start_time = clock();	
	for (int i = 0; i<1000000000; i++)
	{
		operations[0]();    // вызов функции по указателю
	}
	unsigned int end_time = clock(); 
	unsigned int search_time = end_time - start_time;  // 28345 мс больше в 10 раз
	printf("ykazatel  %d ", search_time);	
	
	//////	
	start_time = clock();
	for (int i = 0; i<1000000000; i++)
	{
		z = 1 + 1;
	}
	end_time = clock(); 
	search_time = end_time - start_time; //  2555 мс
	printf("time  %d ", search_time); 
	///////	
	
	_getch();
	return 0;
}


В Delphi если в цикле складывать числа 2516 мс, если процедуре по указателю 2656мс разница небольшая всего около 100 мс.

type
 TMyF = procedure;
var
  a: array [1..2] of TMyF;
var
  Form1: TForm1;
   x,i: integer;
  tf,ts,n:integer;
   procedure f2;
implementation

{$R *.dfm}

procedure f2;
begin
 x:=1+1;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 a[2]:=f2;
 x:=1;

 ts := GetTickCount();
for I := 0 to 1000000000  do
begin
 a[2];
end;
tf := GetTickCount();
mmo1.text:=IntToStr(tf-ts); // 2516 мс

ts := GetTickCount();
for I := 0 to 1000000000  do
begin
 x:=1+1;
end;
tf := GetTickCount();

mmo1.text:=mmo1.text+#13#10+IntToStr(tf-ts); // 2656 мс
 end;
end.
  • Вопрос задан
  • 72 просмотра
Пригласить эксперта
Ответы на вопрос 2
15432
@15432
Системный программист ^_^
Вызов функции всегда несёт большие расходы. При каждом вызове производится выделение памяти в стеке, прыжок, возврат из функции. Эти действия и замедляют выполнение программы. Компилятор Delphi, по-видимому, убрал прыжок и вставил само действие прямо в цикл. Если вы приложите скомпилированные бинарные файлы, я покажу в ассемблерном листинге в чем разница и почему медленно.
Ответ написан
vt4a2h
@vt4a2h Куратор тега C++
Senior software engineer (C++/Qt/boost)
Я советую вам собрать приложение в релизном режиме (со всеми необходимыми оптимизациями) и после этого уже профилировать. Профилирование не в релизном режиме не показательно.
Ну и в целом, вам верно ответили, что вызов функции предполагает большие расходы. Другое дело, что компиляторы очень умные и могут много что оптимизировать. Разумеется не всё.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы