Dokumentation

Leistung und Platzbedarf

Alle Zahlen auf dieser Seite stammen von serde 1.0.229: 339 Dateien, 4.573 Knoten, 9.427 Kanten, 2.443 eingebettete Definitionen. Die Messungen liefen mit greppy 0.4.1 auf einem Apple M5 (10 Kerne, 32 GB RAM, macOS 26.2). Zeiten sind Wandzeit inklusive Prozessstart; greppy --version allein braucht 33 ms.

$ sysctl -n machdep.cpu.brand_string
Apple M5
$ greppy doctor
status: ok
…
inference: preference=auto explicit=false selected=metal device=metal:0000000100000471
…
    device metal:0000000100000471 Apple M5 memory_free=26800144384 memory_total=26800603136
…
stats: files=339 nodes=4573 edges=9427
…

Index und Embeddings

Lauf (serde, Apple M5, Metal) Zeit
Erster Index mit leerem Cache: Graph plus 2.443 Embeddings 59 s (Median aus 3 Läufen: 58,3 / 58,9 / 60,2 s)
Index einer weiteren Kopie (neuer Store), Embeddings aus dem geteilten Cache 2,8 s (Median aus 3 Läufen: 2,3 / 2,8 / 2,8 s)
Erste Graph-Antwort auf einem nicht indexierten Repository (who-calls) 2,6 s

Graph-Abfragen arbeiten, sobald der Graph steht; die Embeddings entstehen im Hintergrund. Eine semantische Suche in dieser Phase meldet Fortschritt und ETA auf stderr und antwortet, sobald die Embeddings fertig sind; auf serde nach 64 s.

greppy bettet nur ein, was noch nicht im Cache liegt. Treffer für dasselbe Modell, denselben Prompt und denselben Inhalt gelten benutzerweit, also auch in einem anderen Worktree oder Repository. greppy index zeigt die Aufteilung:

$ greppy index .
indexed 219 files (120 unsupported, 0 unreadable, 0 oversize, 0 file-limit, 0 time-budget); 4571 nodes extracted; generation 1 (project: serde)
embedded 2443 code spans (0 local-store reused, 0 global-cache hits, 2443 inference misses, 4573 considered, 2150 non-definition skipped, 0 missing-file, 0 invalid-span, 0 oversize, 0 failed, 0 stale pruned)
$ greppy index .
indexed 219 files (120 unsupported, 0 unreadable, 0 oversize, 0 file-limit, 0 time-budget); 4571 nodes extracted; generation 1 (project: serde)
embedded 2443 code spans (0 local-store reused, 2443 global-cache hits, 0 inference misses, 4573 considered, 2150 non-definition skipped, 0 missing-file, 0 invalid-span, 0 oversize, 0 failed, 0 stale pruned)

Abfragen

Das sind warme Zeiten, mit Index und laufenden Inferenz-Daemons, jeweils der Median aus 5 Läufen:

Befehl (serde, Apple M5) Median
greppy who-calls visit_content_map 60 ms
greppy callees visit_content_map 70 ms
greppy read visit_content_map 73 ms
greppy brief visit_content_map 108 ms
greppy search "deserialize a map from buffered content" 108 ms
greppy impact visit_content_map 109 ms

Eine neue Suchfrage bettet die Frage ein und erzeugt die Navigationshinweise für Treffer, die noch keinen haben. Fünf neue Fragen an serde, je einmal gestellt, brauchten 0,53 bis 2,57 s, im Median 2,16 s. Bei derselben Frage ein zweites Mal liegen Embedding und Hinweise schon im Cache: 108 ms.

CUDA und Metal im Vergleich

Das Footprint-Harness misst beide Plattformen mit demselben Ablauf und demselben serde-Commit, aufgezeichnet mit einem Build vor 0.4.1:

Erster Index mit Embeddings brief, warm search, warm
CUDA (RTX A4500) 14,5 s 0,09–0,12 s 0,20 s
Metal (Apple M5) 63,2 s 0,58–0,74 s 0,91–1,04 s

Die aufgezeichneten Läufe findest du in diesen Belegdateien:

Platzbedarf

Diese Größen stammen von greppy 0.4.1 auf macOS arm64:

Installiertes Binary 974 MB
Store pro Repository (serde) 29 MB
Entpackte Modelle 814 MB: EmbeddingGemma 272 MB, Qwen3.5 542 MB
Cache-Quote 10 GiB, mit Garbage Collection
Arbeitsspeicher der Inferenz-Daemons (RSS) Embedding 328 MB, Hinweise 673 MB

Das Binary enthält beide Modelle, ihre Tokenizer, die tree-sitter-Parser und SQLite. Zur Laufzeit lädt greppy nichts herunter. Das Linux-Binary mit CUDA misst im Footprint-Harness (Build vor 0.4.1) 1,11 GB.

Residente Modelle und Daemons

Vorgabe Wert
Ein geladenes Modell bleibt im Speicher 300 Sekunden im Leerlauf
Ein Inferenz-Daemon beendet sich nach 1.800 Sekunden im Leerlauf
Einträge im Workspace-Cache verfallen nach 14 Tagen (GREPPY_STORE_TTL_DAYS), dazu eine unabhängige Größenquote (GREPPY_STORE_MAX_GIB)

greppy cache status --json zeigt die Altersgrenze (ttl_secs) und die Quote (quota_bytes) auf deinem Rechner. Die beiden Daemons teilt sich jeder greppy-Prozess desselben Benutzers.

Verlinkte Worktrees und Agents (0.4.1)

Zwei Messungen aus dem CHANGELOG von 0.4.1 zeigen, was der geteilte Base-Index und der geteilte Inferenz-Cache bringen:

  • Ein verlinkter Worktree eines Repositorys mit 41.012 Spans, die der Haupt-Checkout schon eingebettet hatte, brauchte auf einem Mac der M-Serie 1.520 s. Mit dem geteilten Inferenz-Cache braucht derselbe Worktree 161 s und berührt keine Modelldatei.
  • Navigation über Base und Delta nutzt indizierte Abfragen: path ging von mehr als 120 s auf unter 6 s.

Zeitverhalten, auf das du dich verlassen kannst

Situation Verhalten
Erste Graph-Abfrage auf einem nicht indexierten Repository startet einen Index im Hintergrund und wartet höchstens 2 s auf den Graphen; bei großen Repositories endet die Abfrage danach mit Exit-Code 75 und der Bedingung für den nächsten Versuch
Ein anderer verlinkter Worktree hält den Base-Builder-Lock index wartet höchstens 5 s, dann Exit-Code 75 mit dem Pfad des Locks
Zwei Minuten ohne Fortschritt index status markiert den Job als möglicherweise hängend
Das Kind von bash-smart ist 15 s still ein Lebenszeichen mit PID und Laufzeit, danach eines pro Minute
$ greppy bash-smart -- sleep 20
bash-smart: command still running — pid=19344, elapsed=15s; child output is being captured and will be summarized on exit
ok — exit 0

Auf deinem Repository messen

greppy trial vergleicht auf deinem eigenen Repository einen Lauf ohne und einen mit greppy, ausgeführt mit Pi, und druckt einen JSON-Datensatz greppy.project-trial.v1. Siehe greppy trial --help und Benchmarks und Paper.