win: shrink fd hash table from 2592k to 162k (#4869)

The static initial table reserved space for MxN elements but only used
every Nth element. Removing the excess elements shrinks the table 16x.

I added search/insertion/deletion time logging while here to ensure no
performance regressions.

Fixes: https://github.com/libuv/libuv/issues/4823
This commit is contained in:
Ben Noordhuis 2025-08-24 20:22:54 +02:00 committed by GitHub
parent a9c8da7726
commit 12fbd34475
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 11 additions and 4 deletions

View File

@ -69,7 +69,7 @@ struct uv__fd_hash_bucket_s {
static uv_mutex_t uv__fd_hash_mutex; static uv_mutex_t uv__fd_hash_mutex;
static struct uv__fd_hash_entry_group_s static struct uv__fd_hash_entry_group_s
uv__fd_hash_entry_initial[UV__FD_HASH_SIZE * UV__FD_HASH_GROUP_SIZE]; uv__fd_hash_entry_initial[UV__FD_HASH_SIZE];
static struct uv__fd_hash_bucket_s uv__fd_hash[UV__FD_HASH_SIZE]; static struct uv__fd_hash_bucket_s uv__fd_hash[UV__FD_HASH_SIZE];
@ -82,10 +82,9 @@ static void uv__fd_hash_init(void) {
uv_fatal_error(err, "uv_mutex_init"); uv_fatal_error(err, "uv_mutex_init");
} }
for (i = 0; i < ARRAY_SIZE(uv__fd_hash); ++i) { for (i = 0; i < ARRAY_SIZE(uv__fd_hash); i++) {
uv__fd_hash[i].size = 0; uv__fd_hash[i].size = 0;
uv__fd_hash[i].data = uv__fd_hash[i].data = &uv__fd_hash_entry_initial[i];
uv__fd_hash_entry_initial + i * UV__FD_HASH_GROUP_SIZE;
} }
} }

View File

@ -66,17 +66,25 @@ void assert_removal(int fd) {
/* Run a function for a set of values up to a very high number */ /* Run a function for a set of values up to a very high number */
#define RUN_HASH(function) \ #define RUN_HASH(function) \
do { \ do { \
uint64_t before = uv_hrtime(); \
for (fd = 0; fd < HASH_MAX; fd += HASH_INC) { \ for (fd = 0; fd < HASH_MAX; fd += HASH_INC) { \
function(fd); \ function(fd); \
} \ } \
uint64_t after = uv_hrtime(); \
double seconds = (after - before) / 1e9; \
printf("%.5f hash %s\n", seconds, #function); \
} while (0) } while (0)
/* Run a function for a set of values that will cause many collisions */ /* Run a function for a set of values that will cause many collisions */
#define RUN_COLLISIONS(function) \ #define RUN_COLLISIONS(function) \
do { \ do { \
uint64_t before = uv_hrtime(); \
for (fd = 1; fd < BUCKET_MAX; fd += BUCKET_INC) { \ for (fd = 1; fd < BUCKET_MAX; fd += BUCKET_INC) { \
function(fd); \ function(fd); \
} \ } \
uint64_t after = uv_hrtime(); \
double seconds = (after - before) / 1e9; \
printf("%.5f coll %s\n", seconds, #function); \
} while (0) } while (0)