"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
small got-read-pack performance improvement
To:
gameoftrees@openbsd.org
Date:
Mon, 23 Feb 2026 16:54:30 +0100

Download raw body.

Thread
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) {