Python vs. Rust comparison
The app was rewritten from Python to Rust to deliver significant performance and memory improvements:
| Feature | Python version | Rust version | Improvement |
|---|
| Database processing | ~30s | ~3s | 10x faster |
| Memory usage | ~500 MB | ~150 MB | 70% reduction |
| Search performance | ~2s | ~0.2s | 10x faster |
| Startup time | ~5s | ~1s | 5x faster |
Why Rust is faster
- Compiled to native code — No interpreter overhead. The app runs as a compiled binary optimized for your CPU.
- Zero-copy operations — Memory allocations are minimized by avoiding unnecessary data copies during parsing and search.
- Conservative parsing — Large and partially corrupted database files are handled efficiently without loading invalid data into memory.
- Smart caching — Downloaded databases are stored in
cache/ and reused on subsequent launches, avoiding redundant network requests.
Build optimization
Always use cargo build --release (or cargo run --release) for any real use of the app. Debug builds skip all compiler optimizations and are significantly slower.
- Release build: uses Rust’s default
opt-level=3, enabling full inlining, loop unrolling, and LLVM optimizations.
- Debug build: no optimization. Suitable for development only — noticeably slower for database-heavy workloads.
# Recommended: release build
cargo run --release
# Or compile without running
cargo build --release
Memory optimization
Several constants in avatar_browser_gui.rs bound memory use at runtime:
| Constant | Value | Effect |
|---|
MAX_TEXTURE_CACHE | 256 | Maximum number of avatar images kept in the GPU texture cache |
MAX_PENDING | 48 | Maximum number of concurrent in-flight image fetch requests |
WORKER_COUNT | 4 | Number of background threads used to load images |
PAGE_SIZE | 200 | Number of avatars rendered per page |
- NDJSON streaming —
cache/avatar_entries.ndjson is read line-by-line using a BufReader. The full file is never loaded into memory at once.
- Texture cache cap —
MAX_TEXTURE_CACHE=256 prevents unbounded GPU memory growth as you browse.
- Fetch queue limit —
MAX_PENDING=48 caps concurrent image requests to avoid overwhelming the network or the VRChat CDN.
- Worker threads —
WORKER_COUNT=4 is a tunable trade-off: more workers load images faster but consume more memory and CPU.
- Current algorithm — Linear scan through all loaded avatar entries (O(n)). Simple and correct, but blocks the UI for approximately 2 seconds on large databases.
- Page size — Only
PAGE_SIZE=200 avatars are rendered per page, keeping the frame rate acceptable even with large result sets.
- Known limitation — Search currently runs on the main thread. An async fix is in progress. See Known issues for details.
Use the release build. It is the single most impactful optimization available.
Keep the cache/ directory intact between sessions. Deleting it forces a full database re-download on next launch.
Close other memory-heavy applications if you experience slowdowns. The avatar browser holds up to 256 textures in memory, and competition for RAM can cause stuttering.
Use specific search terms to reduce the result set. Narrower queries complete faster and render fewer avatar cards per page.