Czas wykonania programu C.

209

Mam program C, który ma być uruchamiany równolegle na kilku procesorach. Muszę być w stanie zarejestrować czas wykonania (który może wynosić od 1 sekundy do kilku minut). Szukałem odpowiedzi, ale wszystkie wydają się sugerować użycie clock()funkcji, która następnie polega na obliczeniu liczby zegarów, które program wziął podzielonej przez Clocks_per_secondwartość.

Nie jestem pewien, jak Clocks_per_secondobliczana jest wartość?

W Javie po prostu bierzę czas w milisekundach przed i po wykonaniu.

Czy w C jest coś podobnego? Spojrzałem, ale nie mogę znaleźć sposobu na uzyskanie czegoś lepszego niż drugie rozwiązanie.

Wiem też, że profiler byłby opcją, ale sam zamierzam zaimplementować licznik czasu.

Dzięki

zrozumiałem
źródło
3
jakich platform OS / API używasz / dostępnych? Po prostu zwykłe C?
typo.pl
4
Jest to raczej mały program, po prostu zwykły C
Roger
W tej odpowiedzi szczegółowo
opisałem
czas potrzebny na wykonanie pełnej funkcji stackoverflow.com/a/40380118/6180077
Abdullah Farweez

Odpowiedzi:

344

CLOCKS_PER_SECjest stałą, która jest zadeklarowana w <time.h>. Aby uzyskać czas procesora wykorzystywany przez zadanie w aplikacji C, użyj:

clock_t begin = clock();

/* here, do your time-consuming job */

clock_t end = clock();
double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;

Zauważ, że to zwraca czas jako typ zmiennoprzecinkowy. Może to być dokładniejsze niż sekunda (np. Mierzysz 4,52 sekundy). Precyzja zależy od architektury; na nowoczesnych systemach można łatwo uzyskać 10 ms lub mniej, ale na starszych komputerach z systemem Windows (z okresu Win98) było to bliżej 60 ms.

clock()jest standardem C; działa „wszędzie”. Istnieją funkcje specyficzne dla systemu, na przykład getrusage()w systemach uniksowych.

Java System.currentTimeMillis()nie mierzy tego samego. Jest to „zegar ścienny”: może pomóc ci zmierzyć, ile czasu zajęło wykonanie programu, ale nie mówi ci, ile czasu procesora zostało wykorzystane. W systemach wielozadaniowych (tj. Wszystkich) mogą się one znacznie różnić.

Thomas Pornin
źródło
1
Daje mi bardzo losowy wynik - otrzymuję mieszankę dużej / małej / ujemnej liczby na tym samym fragmencie kodu. GCC 4.7 Linux 3.2 AMD64
3
Tak: clock()zwraca czas w jakiejś wewnętrznej skali zwanej „zegarami” i CLOCKS_PER_SECjest liczbą zegarów na sekundę, więc podzielenie przez CLOCKS_PER_SECdaje czas w sekundach. W powyższym kodzie wartość to a, doubledzięki czemu można ją dowolnie skalować.
Thomas Pornin,
18
Duże ostrzeżenie: clock () zwraca ilość czasu, którą system operacyjny poświęcił na uruchomienie procesu, a nie rzeczywisty czas, który upłynął. Jest to jednak odpowiednie do pomiaru bloku kodu, ale nie do pomiaru upływu czasu w prawdziwym świecie.
2
Powiedział, że chce zmierzyć program wielowątkowy. Nie jestem pewien, czy do tego nadaje się funkcja clock (), ponieważ sumuje czasy działania wszystkich wątków, więc wynik będzie wyglądał tak, jakby kod był uruchamiany sekwencyjnie. Do takich rzeczy używam omp_get_wtime (), ale oczywiście muszę się upewnić, że system nie jest zajęty innymi procesami.
Youda008
1
Powinienem wspomnieć o kilku rzeczach, chociaż ten wątek był bardziej odpowiedni rok temu: CLOCKS_PER_SECma long intwartość 1000000, która daje czas w mikrosekundach, gdy nie jest podzielony; nie cykle zegara procesora. Dlatego nie musi uwzględniać częstotliwości dynamicznej, ponieważ zegar jest tutaj w mikrosekundach (może cykle zegara dla procesora 1 MHz?) Zrobiłem krótki program C drukujący tę wartość i było to 1000000 na moim laptopie i7-2640M, z częstotliwością dynamiczną pozwalającą od 800 MHz do 2,8 GHz, nawet przy użyciu Turbo Boost, aby osiągnąć nawet 3,5 GHz.
DDPWNAGE
111

Jeśli używasz powłoki Unix do uruchamiania, możesz użyć polecenia time.

robić

$ time ./a.out

przyjęcie a.out jako pliku wykonywalnego da ci czas potrzebny na uruchomienie tego

S..K
źródło
3
@acgtyrant, ale tylko dla prostych programów, ponieważ zajmie to cały czas programu, w tym wejście, wyjście itp.
phuclv
1
Jeśli korzystasz z Linuksa i zredukowałeś swój (mikro) test porównawczy do programu z nieznacznym narzutem startowym, np. Statyczny plik wykonywalny, który uruchamia twoją gorącą pętlę przez kilka sekund, możesz użyć, perf stat ./a.outaby uzyskać liczniki wydajności HW dla braków pamięci podręcznej i nieprzewidywalne oddziały oraz IPC.
Peter Cordes,
61

W zwykłej wanilii C:

#include <time.h>
#include <stdio.h>

int main()
{
    clock_t tic = clock();

    my_expensive_function_which_can_spawn_threads();

    clock_t toc = clock();

    printf("Elapsed: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC);

    return 0;
}
Alexandre C.
źródło
6
Najlepsze nazwy zmiennych, które widziałem od jakiegoś czasu. tic = „czas na zegarze”, toc = „czas na zegarze”. Ale także tic-toc = "tik-tock". Tak właśnie odtąd znakuję czas.
Logan Schelly
60

Funkcjonalnie chcesz to:

#include <sys/time.h>

struct timeval  tv1, tv2;
gettimeofday(&tv1, NULL);
/* stuff to do! */
gettimeofday(&tv2, NULL);

printf ("Total time = %f seconds\n",
         (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 +
         (double) (tv2.tv_sec - tv1.tv_sec));

Zauważ, że mierzy to w mikrosekundach, a nie tylko sekundach.

Wes Hardaker
źródło
2
Kompilator MinGW jest oparty na GCC. Więc to zadziała. Ale jeśli użyjesz kompilatora Visual C, pojawi się błąd.
user2550754
11
Tak, będzie działać w systemie Windows z biblioteką ac, która obsługuje połączenie gettimeofday. W rzeczywistości nie ma znaczenia, jaki jest kompilator, wystarczy połączyć go z porządną biblioteką libc. Co w przypadku mingw nie jest domyślnym Windows.
Wes Hardaker,
1
Działa to dla mnie w systemie Windows XP z cygwin gcc i Linux Ubuntu. Właśnie tego chciałem.
Miłość i pokój - Joe Codeswell
gettimeofdayjest przestarzały i nie jest zalecany do nowego kodu. Zamiast tego jego strona podręcznika POSIX zaleca clock_gettime , co pozwala zapytać o CLOCK_MONOTONICto, czy zmiany w zegarze systemowym nie mają na to wpływu, dlatego lepiej jest to interwał. (Zobacz odpowiedź JohnSll ). Na przykład we współczesnych systemach Linux gettimeofday jest zasadniczo opakowaniem dla clock_gettime, który zamienia nanosekundy na mikrosekundy.
Peter Cordes,
12

Większość prostych programów ma czas obliczeń w milisekundach. Przypuszczam, że przyda ci się to.

#include <time.h>
#include <stdio.h>

int main(){
    clock_t start = clock();
    // Execuatable code
    clock_t stop = clock();
    double elapsed = (double)(stop - start) * 1000.0 / CLOCKS_PER_SEC;
    printf("Time elapsed in ms: %f", elapsed);
}

Jeśli chcesz obliczyć środowisko wykonawcze całego programu i korzystasz z systemu uniksowego, uruchom swój program za pomocą polecenia time, takiego jak tentime ./a.out

adimoh
źródło
W systemie Windows co najmniej współczynnik wynosi co najmniej 100, ale nie 1000 i nie jest dokładny
boctulus
6
Ta odpowiedź nie wnosi niczego, co nie było w Alexandre C „s odpowiedź od dwóch Rok wcześniej.
Jonathan Leffler,
3
@ boctulus: 1s to zawsze 1000 ms , także w systemie Windows.
alk
9

Wiele odpowiedzi sugerowało, clock()a następnie CLOCKS_PER_SECpochodziło od time.h. To prawdopodobnie zły pomysł, ponieważ tak /bits/time.hmówi mój plik:

/* ISO/IEC 9899:1990 7.12.1: <time.h>
The macro `CLOCKS_PER_SEC' is the number per second of the value
returned by the `clock' function. */
/* CAE XSH, Issue 4, Version 2: <time.h>
The value of CLOCKS_PER_SEC is required to be 1 million on all
XSI-conformant systems. */
#  define CLOCKS_PER_SEC  1000000l

#  if !defined __STRICT_ANSI__ && !defined __USE_XOPEN2K
/* Even though CLOCKS_PER_SEC has such a strange value CLK_TCK
presents the real value for clock ticks per second for the system.  */
#   include <bits/types.h>
extern long int __sysconf (int);
#   define CLK_TCK ((__clock_t) __sysconf (2))  /* 2 is _SC_CLK_TCK */
#  endif

CLOCKS_PER_SECMożna go więc zdefiniować jako 1000000, w zależności od opcji używanych do kompilacji, a zatem nie wydaje się to dobrym rozwiązaniem.

Stephen
źródło
1
Dzięki za informację, ale czy jest jeszcze lepsza alternatywa?
ozanmuyes
4
To nie jest praktyczny problem: tak, systemy Posix zawsze mają CLOCK_PER_SEC==1000000, ale jednocześnie używają precyzji 1 µs do implementacji clock (); nawiasem mówiąc, ma fajną właściwość, aby zmniejszyć problemy z udostępnianiem. Jeśli chcesz zmierzyć potencjalnie bardzo szybkich zdarzeń, powiedzmy poniżej 1 ms, to należy najpierw martwić o dokładności (lub rozdzielczości) funkcji zegara (), która jest koniecznie grubsze niż 1μs POSIX, ale jest również często znacznie grubsze; typowym rozwiązaniem jest wielokrotne uruchomienie testu; zadane pytanie jednak nie wymagało tego.
AntoineL
Dlaczego nie byłoby to dobre rozwiązanie? Otrzymasz pewną wartość clock(), jeśli podzielisz tę wartość z sobą, CLOCK_PER_SECmasz gwarancję, że uzyskasz czas w sekundach zajmowanych przez procesor. Pomiar rzeczywistej prędkości zegara jest obowiązkiem clock()funkcji, a nie twojej.
Zaffy
9

Odpowiedź Thomasa Pornina jako makra:

#define TICK(X) clock_t X = clock()
#define TOCK(X) printf("time %s: %g sec.\n", (#X), (double)(clock() - (X)) / CLOCKS_PER_SEC)

Użyj tego w ten sposób:

TICK(TIME_A);
functionA();
TOCK(TIME_A);

TICK(TIME_B);
functionB();
TOCK(TIME_B);

Wynik:

time TIME_A: 0.001652 sec.
time TIME_B: 0.004028 sec.
Hklel
źródło
4

Musisz wziąć pod uwagę ten pomiar czasu potrzebnego do uruchomienia programu zależy w dużej mierze od obciążenia, jakie maszyna ma w danym momencie.

Wiedząc, że sposób uzyskania aktualnego czasu w C można osiągnąć na różne sposoby, łatwiejszym jest:

#include <time.h>

#define CPU_TIME (getrusage(RUSAGE_SELF,&ruse), ruse.ru_utime.tv_sec + \
  ruse.ru_stime.tv_sec + 1e-6 * \
  (ruse.ru_utime.tv_usec + ruse.ru_stime.tv_usec))

int main(void) {
    time_t start, end;
    double first, second;

    // Save user and CPU start time
    time(&start);
    first = CPU_TIME;

    // Perform operations
    ...

    // Save end time
    time(&end);
    second = CPU_TIME;

    printf("cpu  : %.2f secs\n", second - first); 
    printf("user : %d secs\n", (int)(end - start));
}

Mam nadzieję, że to pomoże.

Pozdrowienia!

redent84
źródło
4

(Brak tutaj wszystkich odpowiedzi, jeśli administrator systemu zmieni czas systemowy lub strefa czasowa różni się czasem zimowym i zimowym. Dlatego ...)

W przypadku korzystania z Linuksa: clock_gettime(CLOCK_MONOTONIC_RAW, &time_variable); Nie ma to wpływu, jeśli administrator systemu zmieni czas lub mieszkasz w kraju o czasie zimowym innym niż czas letni itp.

#include <stdio.h>
#include <time.h>

#include <unistd.h> /* for sleep() */

int main() {
    struct timespec begin, end;
    clock_gettime(CLOCK_MONOTONIC_RAW, &begin);

    sleep(1);      // waste some time

    clock_gettime(CLOCK_MONOTONIC_RAW, &end);

    printf ("Total time = %f seconds\n",
            (end.tv_nsec - begin.tv_nsec) / 1000000000.0 +
            (end.tv_sec  - begin.tv_sec));

}

man clock_gettime stwierdza:

CLOCK_MONOTONIC
              Clock  that  cannot  be set and represents monotonic time since some unspecified starting point.  This clock is not affected by discontinuous jumps in the system time
              (e.g., if the system administrator manually changes the clock), but is affected by the incremental adjustments performed by adjtime(3) and NTP.
JohnSll
źródło
Czy potrafisz wyjaśnić obliczenia użyte do uzyskania liczby sekund? Nie wiadomo, co się dzieje.
Colin Keenan
1
Nie będzie to (end.tv_nsec - begin.tv_nsec) / 1000000000.0wynik w 0zawsze?
alk
@alk: nie, podzielenie wartości przez doubledosłownych wyzwala int lub longdo doublekonwersji przed podziałem. Oczywiście możesz po prostu trzymać się liczby całkowitej i wydrukować tv_secczęść, a następnie część ułamkową o wartości zerowej %ld.%09ld, ale konwersja do liczby podwójnej jest łatwa, a 53 bity precyzji zwykle wystarczają na czasy testów.
Peter Cordes,
1
(Ups, odejmowanie części nanosekundowej może wymagać przeniesienia do części sekundowej, więc użycie podwójnego i pozostawienie wartości ujemnej pozwala uniknąć tego problemu. Aby użyć łańcucha formatu o całkowitej liczbie całkowitej, potrzebujesz timespec_subtractpodobnej do timeval_subtractsugerowanej w instrukcji glibc : gnu.org/software/libc/manual/html_node/Elapsed-Time.html )
Peter Cordes
3

ANSI C określa tylko funkcje czasu drugiej precyzji. Jednak jeśli pracujesz w środowisku POSIX, możesz użyć gettimeofday () która zapewnia rozdzielczość mikrosekund czasu od czasu epoki UNIX.

Na marginesie, nie zalecałbym używania clock (), ponieważ jest on źle zaimplementowany w wielu (jeśli nie wszystkich?) Systemach i nie jest dokładny, poza tym, że odnosi się to tylko do tego, ile czasu twój program spędził na procesorze i nie całkowity czas trwania programu, który według twojego pytania jest tym, co zakładam, że chciałbyś zmierzyć.

Shinnok
źródło
Norma ISO C (zakładając, że właśnie to oznacza ANSI C ) celowo nie precyzuje funkcji czasowych . W szczególności w przypadku implementacji POSIX lub Windows, precyzja działania zegara ściennego (patrz odpowiedź Thomasa) jest w sekundach. Ale precyzja clock () jest zwykle większa i zawsze 1 μs w Posix (niezależnie od dokładności.)
AntoineL
2

Każde rozwiązanie nie działa w moim systemie.

Mogę się użyć

#include <time.h>

double difftime(time_t time1, time_t time0);
Ankit Chilamatur
źródło
2
Daje to różnicę między dwiema time_twartościami jako podwójną. Ponieważ time_twartości są dokładne z dokładnością do jednej sekundy, ma on ograniczoną wartość w drukowaniu czasu potrzebnego do działania krótko działających programów, chociaż może być przydatny w przypadku programów działających przez długi czas.
Jonathan Leffler,
Z jakiegokolwiek powodu przekazanie pary clock_ts difftimewydaje się działać dla mnie z dokładnością do jednej setnej sekundy. To jest na Linuksie x86. Nie mogę też odjąć stopi startpracować.
ragerdl
@ragerdl: Musisz przejść do difftime() clock() / CLOCKS_PER_SEC, ponieważ oczekuje sekund.
alk
2
    #include<time.h>
    #include<stdio.h>
    int main(){
clock_t begin=clock();

    int i;
for(i=0;i<100000;i++){
printf("%d",i);

}
clock_t end=clock();
printf("Time taken:%lf",(double)(end-begin)/CLOCKS_PER_SEC);
}

Ten program będzie działał jak urok.

Ravi Kumar Yadav
źródło
2

Odkryłem, że zwykły clock (), wszyscy tutaj polecają, z jakiegoś powodu bardzo różni się od uruchomienia do uruchomienia, nawet w przypadku kodu statycznego bez żadnych skutków ubocznych, takich jak rysowanie na ekranie lub czytanie plików. Może tak być, ponieważ procesor zmienia tryby zużycia energii, system operacyjny daje różne priorytety itp.

Tak więc jedynym sposobem, aby niezawodnie uzyskać ten sam wynik za każdym razem przy użyciu clock (), jest uruchomienie mierzonego kodu w pętli wiele razy (przez kilka minut), przy zachowaniu środków ostrożności, aby uniemożliwić kompilatorowi jego optymalizację: nowoczesne kompilatory mogą wstępnie obliczyć kod bez efektów ubocznych działających w pętli i wyjmij ją z pętli, np. używając losowego wejścia dla każdej iteracji.

Po zebraniu wystarczającej liczby próbek do tablicy, sortuje się tę tablicę i przyjmuje środkowy element, zwany medianą. Mediana jest lepsza niż średnia, ponieważ odrzuca ekstremalne odchylenia, jak na przykład antywirus zajmujący cały procesor lub system operacyjny przeprowadzający jakąś aktualizację.

Oto proste narzędzie do pomiaru wydajności wykonania kodu C / C ++, uśredniające wartości zbliżone do mediany: https://github.com/saniv/gauge

Nadal szukam bardziej niezawodnego i szybszego sposobu pomiaru kodu. Prawdopodobnie można by spróbować uruchomić kod w kontrolowanych warunkach na czystym metalu bez żadnego systemu operacyjnego, ale to da nierealistyczny wynik, ponieważ w rzeczywistości system operacyjny się angażuje.

x86 ma te liczniki wydajności sprzętu, w tym rzeczywistą liczbę wykonanych instrukcji, ale dostęp do nich jest trudny bez pomocy systemu operacyjnego, trudny do interpretacji i ma swoje własne problemy ( http://archive.gamedev.net/archive/reference/articles /article213.html ). Mimo to mogą być pomocne w badaniu charakteru szyjki butelki (dostęp do danych lub faktyczne obliczenia tych danych).

SmugLispWeenie
źródło
Tak, nowoczesne procesory x86 pracują bezczynnie znacznie wolniej niż maksymalne turbo. W zależności od ustawień „regulatora” przyspieszenie do maksymalnej prędkości zegara może potrwać milisekundę (Skylake ze sprzętowym zarządzaniem stanem P, zwłaszcza z ustawioną preferencją_wydania energii performance) lub kilkadziesiąt milisekund. en.wikipedia.org/wiki/Dynamic_frequency_scaling . I tak, mediana wyników jest zwykle dobrym wyborem; high-end zwykle ma pewne kolce od interferencji.
Peter Cordes,
Często najlepszym rozwiązaniem, aby uniknąć optymalizacji pracy, jest wprowadzenie danych z wiersza poleceń i zwrócenie wyniku. Lub napisz funkcję w osobnym pliku, mainktóry pobiera argument i zwraca wynik, i nie używaj optymalizacji czasu łącza. Następnie kompilator nie może wstawić go do programu wywołującego. Działa tylko, jeśli funkcja zawiera już jakąś pętlę, w przeciwnym razie narzut wywołania / ret jest zbyt wysoki.
Peter Cordes,
Kompilator może nadal optymalizować dane wejściowe pojedynczego wiersza poleceń z pętli, jeśli jest przetwarzany za pomocą kodu statycznego bez żadnych skutków ubocznych. Dlatego najlepiej jest generować losowe dane wejściowe dla każdej iteracji. Oczywiście rand () powinien być wywoływany poza mierzonym kodem przed pierwszym clock (), ponieważ rand () może równie dobrze skutkować wywołaniem systemowym, próbkując sprzętowy generator entropii (który w starszych systemach był ruchem myszy). Tylko nie zapomnij wydrukować każdego kawałka danych wyjściowych, w przeciwnym razie kompilator może zdecydować, że nie potrzebujesz wszystkich danych wyjściowych w całości lub w części. Można to zrobić za pomocą powiedzmy CRC32.
SmugLispWeenie
Jeśli testowany kod znajduje się w osobnym pliku i nie korzystasz z optymalizacji czasu łącza, kompilator nie może wykonać CSE w celu optymalizacji między wywołaniami. Dzwoniący nie może zakładać niczego o tym, że rozmówca nie ma widocznych efektów ubocznych. Pozwala to na umieszczenie czegoś stosunkowo krótkiego w pętli powtarzania, aby było wystarczająco długo na czas, z po prostu wywołaniem / ret narzutem. Jeśli wpuścisz go do linii, musisz sprawdzić wygenerowany asm, aby upewnić się, że nie wyciągnął obliczenia z pętli, jak mówisz.
Peter Cordes,
Specyficznym dla kompilatora sposobem jest użycie (na przykład) wbudowanego asm GNU C, aby zmusić kompilator do zmaterializowania wyniku w rejestrze i / lub zapomnieć o tym, co wie o wartości zmiennej, bez wprowadzania dodatkowych instrukcji. Odpowiednik „Escape” i „Clobber” w MSVC prowadzi do filmu o profilowaniu i mikrodrukowaniu (rozmowa CppCon 2015 autorstwa Chandlera Carrutha) Nie ma odpowiednika MSVC, ale samo pytanie pokazuje funkcje GNU C i jak z nich korzystać.
Peter Cordes,
0

Niektórym może się przydać inny rodzaj danych wejściowych: dano mi tę metodę pomiaru czasu w ramach uniwersyteckiego kursu programowania GPGPU z NVidia CUDA ( opis kursu ). Łączy metody widoczne we wcześniejszych postach i po prostu publikuję, ponieważ wymagania nadają mu wiarygodność:

unsigned long int elapsed;
struct timeval t_start, t_end, t_diff;
gettimeofday(&t_start, NULL);

// perform computations ...

gettimeofday(&t_end, NULL);
timeval_subtract(&t_diff, &t_end, &t_start);
elapsed = (t_diff.tv_sec*1e6 + t_diff.tv_usec);
printf("GPU version runs in: %lu microsecs\n", elapsed);

Przypuszczam, że możesz pomnożyć przez np., 1.0 / 1000.0Aby uzyskać jednostkę miary, która odpowiada twoim potrzebom.

ワ イ き ん ぐ
źródło
1
gettimeofday jest przestarzały i nie jest zalecany. clock_gettimeZamiast tego zaleca się stronę CLOCK_MONOTONICpodręcznika POSIX , która pozwala zapytać o to, czy zmiany w zegarze systemowym nie mają na to wpływu, dlatego jest lepszy jako interwał. Na przykład w nowoczesnych systemach Linux gettimeofdayjest zasadniczo opakowaniem, clock_gettimektóre zamienia nanosekundy na mikrosekundy. (Zobacz odpowiedź JohnSll).
Peter Cordes,
Ta metoda została dodana przez @Wes Hardaker, główna różnica polega na użyciu timeval_subtract.
ワ イ き ん ぐ
Ok, więc jedyną przydatną częścią twojej odpowiedzi jest nazwa funkcji, której nie definiujesz i której nie ma w standardowej bibliotece. (Tylko w podręczniku glibc: gnu.org/software/libc/manual/html_node/Elapsed-Time.html ).
Peter Cordes,
-2

Porównanie czasu wykonania sortowania bąbelkowego i sortowania selekcyjnego Mam program, który porównuje czas wykonania sortowania bąbelkowego i sortowania selekcyjnego. Aby ustalić czas wykonania bloku kodu, oblicz czas przed i za blokiem według

 clock_t start=clock();
 
 clock_t end=clock();
 CLOCKS_PER_SEC is constant in time.h library

Przykładowy kod:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
   int a[10000],i,j,min,temp;
   for(i=0;i<10000;i++)
   {
      a[i]=rand()%10000;
   }
   //The bubble Sort
   clock_t start,end;
   start=clock();
   for(i=0;i<10000;i++)
   {
     for(j=i+1;j<10000;j++)
     {
       if(a[i]>a[j])
       {
         int temp=a[i];
         a[i]=a[j];
         a[j]=temp;
       }
     }
   }
   end=clock();
   double extime=(double) (end-start)/CLOCKS_PER_SEC;
   printf("\n\tExecution time for the bubble sort is %f seconds\n ",extime);

   for(i=0;i<10000;i++)
   {
     a[i]=rand()%10000;
   }
   clock_t start1,end1;
   start1=clock();
   // The Selection Sort
   for(i=0;i<10000;i++)
   {
     min=i;
     for(j=i+1;j<10000;j++)
     {
       if(a[min]>a[j])
       {
         min=j;
       }
     }
     temp=a[min];
     a[min]=a[i];
     a[i]=temp;
   }
   end1=clock();
   double extime1=(double) (end1-start1)/CLOCKS_PER_SEC;
   printf("\n");
   printf("\tExecution time for the selection sort is %f seconds\n\n", extime1);
   if(extime1<extime)
     printf("\tSelection sort is faster than Bubble sort by %f seconds\n\n", extime - extime1);
   else if(extime1>extime)
     printf("\tBubble sort is faster than Selection sort by %f seconds\n\n", extime1 - extime);
   else
     printf("\tBoth algorithms have the same execution time\n\n");
}
JAGDISH DUDHATE
źródło
4
To naprawdę nie ma niczego nowego w porównaniu z adimoh „s odpowiedzi , poza tym, że wypełnia«»kodu wykonywalnego bloku (lub dwa z nich) z jakiegoś rzeczywistego kodu. I że odpowiedź nie dodaje niczego, co nie było w Alexandre C „s odpowiedź od dwóch Rok wcześniej.
Jonathan Leffler,