#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/wait.h>

#define ITERATIONS 10000

double get_time()
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec + tv.tv_usec / 1000000.0;
}

void *dummy_thread(void *arg)
{
    return NULL;
}

int main()
{
    double t_start, t_end;
    double fork_total = 0, pthread_total = 0;

    /* Measure fork() */
    t_start = get_time();
    for (int i = 0; i < ITERATIONS; i++) {
        pid_t pid = fork();
        if (pid == 0) {
            _exit(0);
        } else if (pid > 0) {
            waitpid(pid, NULL, 0);
        }
    }
    t_end = get_time();
    fork_total = t_end - t_start;

    /* Measure pthread_create() */
    t_start = get_time();
    for (int i = 0; i < ITERATIONS; i++) {
        pthread_t tid;
        pthread_create(&tid, NULL, dummy_thread, NULL);
        pthread_join(tid, NULL);
    }
    t_end = get_time();
    pthread_total = t_end - t_start;

    printf("=== Performance Comparison ===\n");
    printf("Iterations: %d\n", ITERATIONS);
    printf("fork() total time:           %.6f s (avg: %.3f us)\n",
           fork_total, fork_total / ITERATIONS * 1000000);
    printf("pthread_create() total time: %.6f s (avg: %.3f us)\n",
           pthread_total, pthread_total / ITERATIONS * 1000000);
    printf("Ratio (fork/pthread): %.2fx\n", fork_total / pthread_total);
    printf("\nExplanation: fork() creates a new process with a copy of the\n");
    printf("entire address space, which is much heavier than pthread_create()\n");
    printf("which only creates a new thread sharing the same address space.\n");

    return 0;
}
