#include #include #include #include #include #include #include #include #include #define STAT_INTERLEAVED 1 #define STAT_SEMI_INTERLEAVED 2 #define STAT_OPTIMAL 3 struct entry { char *name; ino_t inode; }; #define MAX_ENTRIES 1000000 static struct entry dir_entries[MAX_ENTRIES]; int main () { struct timeval start, end; /* For useful timings, do: sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches' */ gettimeofday (&start, NULL); DIR *links = opendir ("/gnu/store/.links"); size_t count = 0; #if MODE != STAT_INTERLEAVED void sort_entries (void) { int entry_lower (const void *a, const void *b) { return ((struct entry *)a)->inode < ((struct entry *)b)->inode; } qsort (dir_entries, count, sizeof (struct entry), entry_lower); } #endif void stat_entries (void) { for (size_t i = 0; i < count; i++) { struct stat st; lstat (dir_entries[i].name, &st); } } for (struct dirent *entry = readdir (links); entry != NULL; entry = readdir (links)) { assert (count < MAX_ENTRIES); dir_entries[count].name = strdup (entry->d_name); dir_entries[count].inode = entry->d_ino; #if MODE == STAT_INTERLEAVED struct stat st; lstat (entry->d_name, &st); #endif #if MODE == STAT_SEMI_INTERLEAVED if (count++ >= 100000) { sort_entries (); stat_entries (); count = 0; } #else count++; #endif } #if MODE == STAT_SEMI_INTERLEAVED sort_entries (); stat_entries (); #endif gettimeofday (&end, NULL); printf ("%zi dir_entries, %zi seconds" #if MODE != STAT_OPTIMAL " (including stat)" #endif "\n", count, end.tv_sec - start.tv_sec); #if MODE == STAT_OPTIMAL sort_entries (); gettimeofday (&start, NULL); stat_entries (); gettimeofday (&end, NULL); printf ("stat took %zi seconds\n", end.tv_sec - start.tv_sec); #endif return EXIT_SUCCESS; }