From: Stefan Sperling Subject: small got-read-pack performance improvement To: gameoftrees@openbsd.org Date: Mon, 23 Feb 2026 16:54:30 +0100 While enumerating trees, got-read-pack is doing a no-op malloc/free dance per tree entry if we have already traversed the entry. This can be costly when we already have a lot of memory allocated because malloc and free tend to become slower when lots of allocations exist. This match changes the cost to memcpy instead. I have more ideas about how to improve this to avoid mempcy. But we can start with this. ok? diff /home/stsp/src/got path + /home/stsp/src/got commit - dd1ae34cdb71b1414ded065da4834621608a8b3b blob - 4e65a3f8939e6541fe568b471a16f36581536485 file + libexec/got-read-pack/got-read-pack.c --- libexec/got-read-pack/got-read-pack.c +++ libexec/got-read-pack/got-read-pack.c @@ -55,6 +55,10 @@ #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) #endif +#ifndef MINIMUM +#define MINIMUM(a, b) ((a) < (b) ? (a) : (b)) +#endif + static volatile sig_atomic_t sigint_received; static void @@ -1282,22 +1286,24 @@ enumerate_tree(int *have_all_entries, struct imsgbuf * for (i = 0; i < nentries; i++) { struct got_object_qid *eqid = NULL; struct got_parsed_tree_entry *pte = &entries[i]; + struct got_object_id id; char *p; if (!S_ISDIR(pte->mode)) continue; + id.algo = pte->algo; + memcpy(id.hash, pte->id, + MINIMUM(pte->digest_len, sizeof(id.hash))); + if (got_object_idset_contains(idset, &id)) + continue; + err = got_object_qid_alloc_partial(&eqid); if (err) goto done; - eqid->id.algo = pte->algo; - memcpy(eqid->id.hash, pte->id, pte->digest_len); + + memcpy(&eqid->id, &id, sizeof(eqid->id)); - if (got_object_idset_contains(idset, &eqid->id)) { - got_object_qid_free(eqid); - continue; - } - if (asprintf(&p, "%s%s%s", path, got_path_is_root_dir(path) ? "" : "/", pte->name) == -1) {