LINUX.ORG.RU

[C] Замер времени работы функции

 


0

0
float t, t1, t2;  //кусок main
 
  get_int_array();
  t1 = clock();
  k = atoi(argv[1]);
  n = lin_search(1000, k);
  t2 = clock();
  t = t2 - t1;
  printf("Время линейного поиска: %.9f\n", t);

  <----------------skip----------------->

int lin_search(int PartArr, int n)  // функция линейного поиска
{
  int i, t;
  int k;
      
  for (i = 0;i < PartArr;i++)
    {
      if (i_array[i] == n)
        {
          t = i_array[i];
          return t;
        }
  }  
 
  return -2;
}

~/source $ gcc search.c 
~/source $ ./a.out 99
Время линейного поиска: 0.000000000000000
Найден:	99

Ничего не пойму, время постоянно по нулям, если ставлю первый клок до функции по наполнению массива то время увеличивается, но мне нужно время работы функции поиска, для последующего сравнения. ЧЯДНТ?

Также увеличение количества элементов в массиве не помогает, остаются нули и sleep(); тоже.

★★

Последнее исправление: wlan (всего исправлений: 2)

clock(3) не для этого, читай ман

struct timeval tv1, tv2;

gettimeofday(&tv1, NULL);
/* some fancy code */
gettimeofday(&tv2, NULL);

printf("time elapsed: %d usec\n", tv2.tv_usec - tv1.tv_usec);
beastie ★★★★★
()
Ответ на: комментарий от beastie

Cпасибо большое, я уже всю голову поломал :)

//Чтобы я еще в какой жж смотрел варианты решения :(

wlan ★★
() автор топика
Ответ на: комментарий от wlan

небольшое дополнение — забыл одну вещь, пардон:

#include <sys/time.h>

struct timeval ta, te;

gettimeofday(&ta, NULL);
/* some fancy code */
gettimeofday(&te, NULL);

printf("time elapsed: %lf sec\n", te.tv_sec - ta.tv_sec + (te.tv_usec - ta.tv_usec)/1000000.0);

с clock в принципе тоже можно, но оно меряет не совсем то, что тебе скорей всего надо:

#include <time.h>

clock_t ca, ce;

ca = clock();
/* some fancy code */
ce = clock();

printf("time spent on CPU: %lf sec\n", (ce - ca)/(double)CLOCKS_PER_SEC);
beastie ★★★★★
()
Ответ на: комментарий от beastie

Второй вариант с клоком выводил нули почему-то, позже попробую оба варианта

wlan ★★
() автор топика

А с каких это пор clock() возвращает float?

whoami
()
Ответ на: комментарий от mv

> Настоящие суровые мужики меряют время oprofile'ом.

systemtap'ом

Вот возьмут его в ядро - будем мерять им.

или вообще rdtsc =)

Не, так поступают красноглазые щенки :D

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Вот возьмут его в ядро - будем мерять им.

А что там брать? В свете сопротивления Линуса ютрейсу авторы stap'а, говорят, оперативно переписали его на юпробс. Так что всё чотка.

mv ★★★★★
()
Ответ на: комментарий от tailgunner

Дядь, ты лучше не тролль а скажи как реализовать одну и ту же функцию с флоатами и интами но не переписывая ее снова

типа int||float name (int||float a, int||float b);

и если чел вводит аргументом флоат то мы забиваем массив флоатами ищем в этом массиве и сортируем, а если инты то забиваем массив интами и тд.

Надеюсь понятно объяснил, нужна именно сишная реализация, если такое вообще есть

wlan ★★
() автор топика
Ответ на: комментарий от Zenom

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

wlan ★★
() автор топика
Ответ на: комментарий от wlan

Можно сделать так: нужные тебе функции принимают аргументами ссылки на функции для генерации массива и сравнения элементов. И для того, чтобы добавить возможность работы с новым типом нужно будет реализовать эти самые функции.

Zenom ★★★
()
Ответ на: комментарий от wlan

>а если инты то забиваем массив интами и тд.
void *func(void *, const char*)

где const char * указатель на строку «INT» или «FLOAT»

а потом void* ---> int[]

dimon555 ★★★★★
()
Ответ на: комментарий от dimon555

Плохое решение. Во-первых, для добавления, скажем, строк, придётся перелопачивать саму функцию. Во-вторых, если опечататься, то компилятор не укажет на ошибку.

Zenom ★★★
()
Ответ на: комментарий от Zenom

> Плохое решение.

Для Си - нормально. Только, конечно, первым аргументом должен быть enum { FLOAT, INT, WHATEVER }, а вторым - void *.

tailgunner ★★★★★
()
Ответ на: комментарий от Zenom

> Может у меня мозг отравлен функциональщиной

Ты скала-фанбой епт %)

но мой подход мне кажется лучше.

Попробуй записать его на Си без принудительных преобразований типов.

tailgunner ★★★★★
()
Ответ на: комментарий от Zenom

да, но при этом процесс может пол-часа ждать какого-нибудь IO и быть при этом только пол-микросекунды на процессоре. gettimeofday даст тебе общее время выполнения, а вот clock только второе.

beastie ★★★★★
()
Ответ на: комментарий от tailgunner

SystemTap уже можно построить без патча на ядро?

Из арчевского aur ставится без левых ядер и т.п. А в арче ядра ванильные юзаются.

mv ★★★★★
()
Ответ на: комментарий от Zenom

В c нет перегрузки функций. Делай две.

слегка спорное утверждение — с С есть указатели на функции. чем же не перегрузка?

но две функции таки делать прийдётся.

beastie ★★★★★
()
Ответ на: комментарий от wlan

тупое решение ``влоб''

#include <stdio.h>

float fname(float, float);
int iname(int, int);

#define name(a, b) \
      (sizeof(a) == sizeof(float)) ? fname((a), (b)) : iname((a), (b))

float
fname(float a, float b)
{
        return a + b;
}

int
iname(int a, int b)
{
        return a + b;
}

int
main()
{
        int i, *p;
        float f;

        i = name(1, 2);
        f = name(2.0, 3.0);

        printf("%d\n%f\n", i, f);

        return 0;
}
beastie ★★★★★
()
Ответ на: комментарий от tailgunner

>Попробуй записать его на Си без принудительных преобразований типов.

Я ж не на преобразование типов ругался.

А так qsort(3posix) хороший пример.

Zenom ★★★
()
Ответ на: комментарий от tailgunner

Кхм, таки это быдлокод? Я и сам думал реализовать через препроцессор.

Или мне идти ботать указатели функции или тупо написать каждую функцию в двух экземплярах?

wlan ★★
() автор топика
Ответ на: комментарий от wlan

Кхм, таки это быдлокод?

Да. Причем автор еще и пытался умничать.

Прогони вот это и попытайся объяснить результат:


#include <stdio.h> 
 
float fname(float, float); 
int iname(int, int); 
 
#define name(a, b) \ 
      (sizeof(a) == sizeof(float)) ? fname((a), (b)) : iname((a), (b)) 
 
float 
fname(float a, float b) 
{ 
        printf("%s\n", __func__);
        return a + b; 
} 
 
int 
iname(int a, int b) 
{ 
        printf("%s\n", __func__);
        return a + b; 
} 
 
int 
main() 
{ 
        int i, *p; 
        float f; 
 
        i = name(1, 2); 
        f = name(2.0, 3.0); 
 
        printf("%d\n%f\n", i, f); 
 
        return 0; 
}

Или мне идти ботать указатели функции или тупо написать каждую функцию в двух экземплярах?

Я бы сделал так, как я сказал :)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Я бы сделал так, как я сказал :)

мой скилл сей и херовый парсер чото сомневается что ты имел ввиду :(

wlan ★★
() автор топика
Ответ на: комментарий от wlan
enum ty { FLOAT, INT } ;

void foo(enum ty t, void *p)
{
  switch (t) {
    case FLOAT:
      { float *float_dest = p; /* забиваем массив float */ }
      break;
    case INT:
      { int *int_dest = p; /* забиваем массив int */ }
      break;
  }
} 

но это масштабируется плохо - если тебе понадобится несколько функций, то лучше делать так, как сказал Zenom.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Прогони вот это и попытайся объяснить результат:

и что ты этим хотел сказать?

а по поводу кода — это так, балавство и IRL ему не место, зато тупо и просто. указателями красивее будет. но нужно ли оно вообще?

beastie ★★★★★
()
Ответ на: комментарий от beastie

Прогони вот это и попытайся объяснить результат:

и что ты этим хотел сказать?

Вот вывод:

$ ./a.out 
fname
iname
3
5.000000
$

Тебе не кажется, что первой должна быть вызвана iname? А как поведет себя твой макрос при разных типах аргументов?

а по поводу кода — это так, балавство и IRL ему не место

Не следовало вообще постить этот код в топике, где его могут увидеть дети %)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Да у меня несколько их, 1: наполнение массива, 2: линейный поиск по массиву 3: сортировка 4: поиск методом золотого сечения и в мэйне сравнение способов поиска. Нужно все эти функции реализовать, под инт и флоат. Думаю попробую сделать как говорит ернеста

wlan ★★
() автор топика
Ответ на: комментарий от tailgunner

да, согласен — прокол. hot-fix: %s/float/double/g

ладно, считай, что я этого не постил и вообще меня тут не было. побаловались и хватит.

хотя конечно было бы интерессно посмотреть на _красивое_ решение этой задачи, даже если и полезности в реальной жизни тут ноль без палочки.

beastie ★★★★★
()
Ответ на: комментарий от tailgunner

Тебе не кажется, что первой должна быть вызвана iname?

Как ни странно, но вот так работает правильно:

#include <stdio.h>  
  
float fname(float, float);  
int iname(int, int);  
#define name(a, b) \
      (sizeof(a) == sizeof(float)) ? iname((a), (b)) : fname((a), (b))  
float fname(float a, float b){  
        printf("fname: %.1f\n", a+b); 
}  
  
int iname(int a, int b){  
        printf("iname: %d\n",a+b); 
}  
  
int main(){  
        int i, *p;  
        float f;  
        i = name(1, 2);  
        f = name(2.0, 3.0);  
  	name(2.0, 5);
        return 0;  
} 
А вообще, чтобы делать функции, работающие с разными типами данных, удобнее передавать им в качестве аргумента void*, а потом уже делать преобразование типа. А можно сделать, как в алгоритмах сортировки: функция принимает одним аргументом void**, а другим - int (*fn)() - указатель на функцию сравнения. Кажется мне, это самый гибкий способ.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

> Как ни странно, но вот так работает правильно:

Что странного? Ты переставил iname и fname в тернарном операторе. У beastie он хоть понятный был, а у тебя - вообще бессмысленный.

К.О. считает своим долгом напомнить, что размеры float и int могут быть одинаковыми.

tailgunner ★★★★★
()
Ответ на: комментарий от beastie

> было бы интерессно посмотреть на _красивое_ решение этой задачи

В Си это невозможно. В лучшем случае можно сделать указатель на функцию или вектор таких указателей.

tailgunner ★★★★★
()
Ответ на: комментарий от Eddy_Em

есть ещё typeof, его вроде как применять корректнее в вашем случае.

(typeof(x)==typeof(float)?....)

хотя всё одно получается - гланды через ж..пу

MKuznetsov ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.