Skip to content

Performance

xjoker edited this page Jul 21, 2026 · 1 revision

Performance

delamain is built for headless, concurrent, low-memory operation. This page summarizes real measurements on a large Android app and contrasts the headless architecture with a conventional GUI-mode baseline — a JADX‑GUI‑backed MCP server that drives decompilation through the desktop engine — on identical workloads.

How this was measured. One large production APK (~238,000 classes), a single 62 GB host, client on --network host (localhost — no LAN jitter, absolute numbers comparable). delamain ran with -Xmx38g -XX:+UseG1GC. P50 over 200 samples × 3 repeats after warmup discards; 503s / timeouts counted separately from latency. These are indicative of the architecture on a large app, not a universal guarantee — your APK, host, and heap will differ.

Concurrency reliability — the headline

The headless design keeps a per-class decompile lock plus a persistent CodeStore and usage graph, so it never serializes on a single global decompile lock the way a GUI-driven engine does. Under concurrency this is the sharpest difference:

Workload (concurrency) delamain GUI-mode baseline
smali @ c8 / c24 100% success (0% 503) 44% / 28% 503
xref, class-level @ c1–c24 100% success (0% 503) 100% 503 (every concurrency level)

delamain returns 0% 503 across every workload and concurrency level, while the GUI-mode baseline sheds smali requests under load and cannot serve class-level xref at all under concurrency (its global decompile lock serializes everything). An earlier baseline run also saw ~10% 503 on class_source at 10-way concurrency, from JVM heap-pressure tripping its OOM breaker.

Steady-state latency (hot, P50 ms)

REST layer, concurrency 1 / 8 / 24:

Workload delamain c1 c8 c24
metadata search 26 298 628
class_source (cached) 5 26 120
smali 5.6 36 135
xref (class-level) 2.7 23 102

A later tuned build measured cached class_source at 4.7 ms P50 (c1) / 23.4 ms (c8) and class-level xref at 2.4 ms / 22.9 ms, at 0% error.

Noise floor (/health P50): delamain 2.6 ms vs the GUI-mode baseline 21 ms — roughly 8× lower base overhead.

MCP gateway overhead

The Python MCP gateway adds ~12–15 ms/call over the raw REST layer (MCP protocol + serialization + one extra hop): metadata +13 ms, class_source +15 ms, smali +14 ms at c1. The full MCP chain stays 100% success.

Startup: cold vs hot

Metric Cold (empty index volume) Hot (FAST_RESTORE, reused index)
Serveable (port open, class tree loaded) ~24 s ~11–58 s (OS page-cache variance)
Full warmup 1033 s (~17 min) ~40 s (≈26× faster)
First-touch uncached class_source ~15 s ms-level after restore
On-disk index size 3.7 GB reused

Cold warmup is dominated by Phase-1 full decompile (58%) + use-places harvest (33%). A persisted index volume (see Deployment → prebaked index) collapses restart to ~40 s. Capabilities open progressively during warmup — get_warmup_status reports overall progress, an ETA, and a per-capability ready | warming map (metadata_search → class_source → smali → code_search → xref_class_level → precise_xref_snippets).

Memory

On the same ~238K-class app, delamain held ~10 GB steady-state heap (24% of a 38 GB max) with 0 OOM. Under pressure it uses heap-aware degradation — skipping the trigram / use-places index rather than crashing — so it stays alive on constrained hosts. See Configuration for the memory knobs (JADX_CACHE_MAX_GB, warmup worker counts, trigram caps).

Caveats (stated honestly)

  • Measured on one large APK, on one host (localhost), with a single cold run — treat as indicative, not a guarantee.
  • The GUI-mode comparison is at the REST layer; the baseline's MCP endpoint used a separate auth and was not measured end-to-end.
  • Latency and warmup time scale with your APK size, host CPU/RAM, and JVM heap.

See also: Deployment · Configuration · FAQ · Development-and-Integration

Clone this wiki locally