/* * MEDIUM: Sequential Linked List Traversal * ========================================= * This program creates a linked list with nodes allocated contiguously, * representing the best-case scenario for linked lists. * Still slower than arrays due to pointer chasing overhead. * * Compile: make list_sequential * Run: ./list_sequential * Profile: perf stat -e cache-misses,cache-references ./list_sequential */ #include #include #include #define N 10000000 /* 10 million elements */ struct node { int value; struct node *next; }; double get_time(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return ts.tv_sec + ts.tv_nsec / 1e9; } long sum_list(struct node *head) { long sum = 0; struct node *curr = head; while (curr != NULL) { sum += curr->value; curr = curr->next; } return sum; } /* * Create linked list with nodes allocated sequentially (best case for list) * All nodes allocated in one contiguous block, linked in order. */ struct node *create_list_sequential(int n) { struct node *nodes = malloc(n * sizeof(struct node)); if (!nodes) { perror("malloc list"); exit(1); } for (int i = 0; i < n - 1; i++) { nodes[i].value = i % 100; nodes[i].next = &nodes[i + 1]; } nodes[n - 1].value = (n - 1) % 100; nodes[n - 1].next = NULL; return nodes; } int main(void) { printf("Sequential Linked List Traversal (%d elements)\n", N); printf("All nodes allocated contiguously - best case for linked list.\n"); printf("Still has pointer chasing overhead vs array.\n\n"); printf("Creating sequential linked list...\n"); struct node *list = create_list_sequential(N); /* Warm up */ sum_list(list); double start = get_time(); long result = sum_list(list); double elapsed = get_time() - start; printf("Sequential list sum: %ld in %.4f seconds\n\n", result, elapsed); printf("To see cache behavior, run:\n"); printf(" perf stat -e cache-misses,cache-references ./list_sequential\n"); free(list); return 0; }