readstdin: reduce memory-usage by duplicating the line from getline() - dmenu -… | |
git clone git://git.suckless.org/dmenu | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit dfbbf7f6e1b22ccf9e5a45d77ee10995577fb4fc | |
parent ba1a347dcaba055f824161007dfee60db3ea785b | |
Author: Hiltjo Posthuma <[email protected]> | |
Date: Wed, 8 Mar 2023 21:20:52 +0100 | |
readstdin: reduce memory-usage by duplicating the line from getline() | |
Improves upon commit 32db2b125190d366be472ccb7cad833248696144 | |
The getline() implementation often uses a more greedy way of allocating memory. | |
Using this buffer directly and forcing an allocation (by setting it to NULL) | |
would waste a bit of extra space, depending on the implementation of course. | |
Tested on musl libc and glibc. | |
The current glibc version allocates a minimum of 120 bytes per line. | |
For smaller lines musl libc seems less wasteful but still wastes a few bytes | |
per line. | |
On a dmenu_path listing on my system the memory usage was about 350kb (old) vs | |
30kb (new) on Void Linux glibc. | |
Side-note that getline() also reads NUL bytes in lines, while strdup() would | |
read until the NUL byte. Since dmenu reads text lines either is probably | |
fine(tm). Also rename junk to linesiz. | |
Diffstat: | |
M dmenu.c | 9 +++++---- | |
1 file changed, 5 insertions(+), 4 deletions(-) | |
--- | |
diff --git a/dmenu.c b/dmenu.c | |
@@ -550,11 +550,11 @@ static void | |
readstdin(void) | |
{ | |
char *line = NULL; | |
- size_t i, junk, itemsiz = 0; | |
+ size_t i, itemsiz = 0, linesiz = 0; | |
ssize_t len; | |
/* read each line from stdin and add it to the item list */ | |
- for (i = 0; (len = getline(&line, &junk, stdin)) != -1; i++) { | |
+ for (i = 0; (len = getline(&line, &linesiz, stdin)) != -1; i++) { | |
if (i + 1 >= itemsiz) { | |
itemsiz += 256; | |
if (!(items = realloc(items, itemsiz * sizeof(*items))… | |
@@ -562,9 +562,10 @@ readstdin(void) | |
} | |
if (line[len - 1] == '\n') | |
line[len - 1] = '\0'; | |
- items[i].text = line; | |
+ if (!(items[i].text = strdup(line))) | |
+ die("strdup:"); | |
+ | |
items[i].out = 0; | |
- line = NULL; /* next call of getline() allocates a new line */ | |
} | |
free(line); | |
if (items) |