From 5a40e88f3c4b2db97dbd24ce53f738454bf2b01c Mon Sep 17 00:00:00 2001 From: "debing.sun" Date: Fri, 15 Aug 2025 22:56:56 +0800 Subject: [PATCH] Avoid the overhead from snprintf --- src/zmalloc.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/zmalloc.c b/src/zmalloc.c index 39386c0dbea..a2632b970fd 100644 --- a/src/zmalloc.c +++ b/src/zmalloc.c @@ -737,33 +737,46 @@ size_t zmalloc_get_rss(void) { size_t zmalloc_get_frag_smallbins_by_arena(unsigned int arena) { unsigned nbins; size_t sz, frag = 0; - char buf[100]; + + /* Pre-convert mallctl paths to MIB for better performance. + * This eliminates snprintf and string parsing overhead in the loop. */ + size_t bin_size_mib[8], bin_nregs_mib[8], curregs_mib[8], curslabs_mib[8]; + size_t bin_size_miblen = 8, bin_nregs_miblen = 8, curregs_miblen = 8, curslabs_miblen = 8; sz = sizeof(unsigned); assert(!je_mallctl("arenas.nbins", &nbins, &sz, NULL, 0)); + + /* Convert all patterns to MIB (required before using je_mallctlbymib) */ + assert(!je_mallctlnametomib("arenas.bin.0.size", bin_size_mib, &bin_size_miblen)); + assert(!je_mallctlnametomib("arenas.bin.0.nregs", bin_nregs_mib, &bin_nregs_miblen)); + assert(!je_mallctlnametomib("stats.arenas.0.bins.0.curregs", curregs_mib, &curregs_miblen)); + assert(!je_mallctlnametomib("stats.arenas.0.bins.0.curslabs", curslabs_mib, &curslabs_miblen)); + for (unsigned j = 0; j < nbins; j++) { size_t curregs, curslabs, reg_size; uint32_t nregs; /* The size of the current bin */ - snprintf(buf, sizeof(buf), "arenas.bin.%u.size", j); + bin_size_mib[2] = j; sz = sizeof(size_t); - assert(!je_mallctl(buf, ®_size, &sz, NULL, 0)); + assert(!je_mallctlbymib(bin_size_mib, bin_size_miblen, ®_size, &sz, NULL, 0)); /* Number of used regions in the bin */ - snprintf(buf, sizeof(buf), "stats.arenas.%u.bins.%u.curregs", arena, j); + curregs_mib[2] = arena; + curregs_mib[4] = j; sz = sizeof(size_t); - assert(!je_mallctl(buf, &curregs, &sz, NULL, 0)); + assert(!je_mallctlbymib(curregs_mib, curregs_miblen, &curregs, &sz, NULL, 0)); /* Number of regions per slab */ - snprintf(buf, sizeof(buf), "arenas.bin.%u.nregs", j); + bin_nregs_mib[2] = j; sz = sizeof(uint32_t); - assert(!je_mallctl(buf, &nregs, &sz, NULL, 0)); + assert(!je_mallctlbymib(bin_nregs_mib, bin_nregs_miblen, &nregs, &sz, NULL, 0)); /* Number of current slabs in the bin */ - snprintf(buf, sizeof(buf), "stats.arenas.%u.bins.%u.curslabs", arena, j); + curslabs_mib[2] = arena; + curslabs_mib[4] = j; sz = sizeof(size_t); - assert(!je_mallctl(buf, &curslabs, &sz, NULL, 0)); + assert(!je_mallctlbymib(curslabs_mib, curslabs_miblen, &curslabs, &sz, NULL, 0)); /* Calculate the fragmentation bytes for the current bin and add it to the total. */ frag += ((nregs * curslabs) - curregs) * reg_size;