Измерение времени, потраченного на выполнение функции - PullRequest
0 голосов
/ 23 мая 2018

редактировать: я понял это.Второй алгоритм работал настолько эффективно, что время даже не записывалось с входом <100 000 </p>

. Я пытаюсь измерить, сколько времени требуется для выполнения определенного алгоритма, который я реализовал в функции.Я включил <time.h> и окружаю функцию вокруг time_t переменных.Он отлично работает для моей первой реализации, но не для моей второй.

Нужно ли мне закрывать тактовый поток (не могу придумать лучшей работы) между использованиями?Вроде как вы закрываете поток Scanner в Java-программе.Вот мой код на тот случай, если я не очень хорошо его объясню.

switch(choice) {
    case 1:
        printf("Beginning prefixAverages1\n");
        clock_t begin1 = clock();
        int *a1 = prefixAverages1(input);
        clock_t end1 = clock();
        double time_spent1 = (double)(end1 - begin1) * 1000.0 / CLOCKS_PER_SEC;
        free(a1);
        printf("Algorithm took %f milliseconds to execute \n", time_spent1);
        break;
    case 2:
        printf("Beginning prefixAverages2\n");
        clock_t begin2 = clock();
        int *a2 = prefixAverages2(input);
        clock_t end2 = clock();
        double time_spent2 = (double)(end2 - begin2) * 1000.0 / CLOCKS_PER_SEC;
        free(a2);
        printf("Algorithm took %f milliseconds to execute \n", time_spent2);
        break;
    default:
        printf("Invalid input!");
        break;
}

Время отображается правильно в моем первом случае, но не во втором.Я попытался провести какое-то исследование, но я не могу найти ничего конкретного для моего сценария.

При запуске случая 1, в зависимости от ввода, у меня есть время для запуска 600-1000 мс (что звучит примерно так:право).Когда я запускаю дело 2, независимо от ввода, я получаю 00.000

Вот мои функции, если это поможет:

int* prefixAverages1(int input) {
    int x[input];
    int *a = malloc(input*sizeof(*a));
    srand(time(NULL));  

    for(int i = 0; i < input; i++) {
        int sum = 0;
        for(int j = 0; j < i; j++) {
            int r = rand() % 100;
            x[j] = r;
            sum = sum + x[j];
        }
        a[i] = sum / (i+1);
    }
    return a;
}

int* prefixAverages2(int input) {
    int sum = 0;
    int x[input];
    int *a = malloc(input*sizeof(*a));
    srand(time(NULL));  

    for(int i = 0; i < input; i++) {
        int r = rand() % 100;
        x[i] = r;
        sum = sum + x[i];
        a[i] = sum / (i+1);
    }
    return a;
}

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Я более знаком с этим в Windows, используя QueryPerformanceCounter, так что я, вероятно, делаю все здесь плохие вещи, но основная идея для измерения коротких циклов:

int main()
{
  printf("Beginning prefixAverages2\n");
  timespec begin, end;
  clock_gettime(CLOCK_REALTIME, &begin);
  int *a1 = prefixAverages2(50000);
  clock_gettime(CLOCK_REALTIME, &end);
  double time_spent = (end.tv_nsec - begin.tv_nsec) / 1000;
  time_spent += (end.tv_sec - begin.tv_sec) *1000000;

  free(a1);
  printf ("Time spent %f microseconds", time_spent);
}

Вывод:

Beginning prefixAverages2
Time spent 427.000000 microseconds

PS - Оказывается, clock() не использует время стены: Рассчитывает время выполнения при использовании sleep ()

0 голосов
/ 23 мая 2018

Хотя я не знаю, почему второй вариант может быть 0, поскольку две функции имеют одинаковую сигнатуру, вы можете устранить избыточный код с помощью указателей функций.

void do_benchmark( const char *name, int*(*functionPtr)(int), int input ) {
    printf("Beginning %s\n", name);
    clock_t begin = clock();
    int *ret = (*functionPtr)(input);
    clock_t end = clock();
    double time_spent = (double)(end - begin) * 1000.0 / CLOCKS_PER_SEC;
    free(ret);
    printf("Algorithm took %f milliseconds to execute \n", time_spent);
}

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

switch(choice) {
    case 1:
        do_benchmark("prefixAverages1", &prefixAverages1, input);
        break;
    case 2:
        do_benchmark("prefixAverages2", &prefixAverages2, input);
        break;
    default:
        printf("Invalid input!");
        break;
}

Обратите внимание, что clock может дать сбой.

Если используется процессорное времянедоступно или его значение не может быть представлено, функция возвращает значение (clock_t) (- 1).

Вы захотите проверить этот сбой.

if( begin == (clock_t)-1 ) {
    fprintf(stderr, "Begin time not available.\n");
}
else if( end == (clock_t)-1 ) {
    fprintf(stderr, "End time not available.\n");
}
else {
    double time_spent = (double)(end - begin) * 1000.0 / CLOCKS_PER_SEC;
    printf("Algorithm took %f milliseconds to execute \n", time_spent);
}
...