Бенчмарки
Измерено, а не обещано.
Release-сборка на macOS arm64 · 10 ядер · 16 × ~2047 KB файлов. Все сценарии офлайн — без сети и LLM — поэтому их можно гонять в CI.
Накладные расходы диспетчеризации
Сколько машинного кода разделяет вызов инструмента LLM и собственно работу.
| Измерение | Итерации | На вызов |
|---|---|---|
| registry.execute (raw dispatch) | 300 | 5140 µs |
| execute_batch, 1 call | 300 | 7614 µs |
| execute_batch, 8 calls (amortized) | 320 | 5893 µs |
| ToolCall args serde round-trip | 100000 | 752 ns |
Overhead исполнителя над сырой диспетчеризацией: 2473 мкс на батч из одного вызова; амортизированный overhead падает до 753 мкс на вызов в батче из 8.
Fathom vs последовательно — I/O-нагруженные
16 × file_read несовпадающих файлов по ~2047 КБ.
16/16 вызовов успешно (join_all), 16/16 (spawn); все классифицированы как параллельно-безопасные.
Fathom vs последовательно — CPU-нагруженные
8 × parse_html таблицы ~1 МБ (3000 строк), селектор `tr.item`, режим texts.
join_all делит один поток — spawn распределяет CPU-работу по ядрам.
Смешанный батч — автоматическое разбиение
Реалистичный ход агента: чтения (параллельно-безопасные) + записи (последовательно) в одном батче. 5 — конкурентно, 3 — последовательно; суммарно 70.9 мс, 8 успешно. Порядок сохранён.
| Инструмент | Фаза | Успех | Длительность |
|---|---|---|---|
| file_read (r0) | parallel | ✅ | 16 ms |
| file_read (r1) | parallel | ✅ | 20 ms |
| file_read (r2) | parallel | ✅ | 25 ms |
| file_read (r3) | parallel | ✅ | 29 ms |
| file_write (w0) | sequential | ✅ | 2 ms |
| file_write (w1) | sequential | ✅ | 0 ms |
| file_write (w2) | sequential | ✅ | 0 ms |
| grep (g0) | parallel | ✅ | 65 ms |
Масштабирование parse_html с размером документа
Тот же селектор (`tr.item`, texts-режим), растущий размер документа. До 531k строк/с.
| Документ | Строки | Ср. парсинг | Пропускная способность |
|---|---|---|---|
| 6 KB | 100 | 0.19 ms | 531,915 rows/s |
| 63 KB | 1000 | 4.08 ms | 245,339 rows/s |
| 191 KB | 3000 | 9.55 ms | 314,268 rows/s |
| 773 KB | 12000 | 34.22 ms | 350,723 rows/s |
Пропускная способность extract_json
~4 МБ JSON-документ с 20 000 объектов. Без сохранения состояния и параллельно-безопасен (пере-парсится на каждый вызов).
| Запрос | Итерации | Среднее |
|---|---|---|
| wildcard scan `items[*].value` (limit 500) | 10 | 71.24 ms |
| deep single key `items.12345.meta.score` | 10 | 67.78 ms |
| top-level key `total` | 10 | 43.47 ms |
web_feed (quick-xml) — масштабирование и параллелизм
Локальный RSS-фикстур; устойчивость к размеру фида и CPU-скорости при параллелизме. До 1.1M элементов/с.
| Элементы фида | Ср. парсинг | Элементов/с |
|---|---|---|
| 1000 | 0.93 ms | 1,077,586 |
| 5000 | 4.78 ms | 1,045,588 |
| 12000 | 10.81 ms | 1,110,391 |
| 20000 | 27.10 ms | 738,089 |
8 × web_feed фида ~5 МБ; 8/8 успешно в обоих режимах.
code_symbols / repo_map — извлечение символов
240 Rust-файлов (~14 КБ каждый, 40 функции + 40 структур + impl на файл).
| Инструмент | Режим | Время выполнения | Элементы |
|---|---|---|---|
| code_symbols | single | 7.2 ms | 7007 lines |
| repo_map | single | 34.2 ms | 4330 lines |
8/8 сканирований символов успешно (join_all), 8/8 (spawn).
Семантическая память — absorb / search / digest
Офлайн TF-IDF эмбеддер (без сети и LLM); in-memory SQLite.
| Батч | Поглощено | Время выполнения | На факт |
|---|---|---|---|
| 10 | 10 | 10.2 ms | 1020 µs |
| 100 | 89 | 9.4 ms | 94 µs |
| 500 | 335 | 82.6 ms | 165 µs |
Повторный absorb 100 известных фактов: 93 пропущено, 0 создано за 5.1 мс (быстрый путь дедупликации).
| Гибридный поиск | Совпадения | Медиана |
|---|---|---|
| Acme revenue units filing | 5 | 2.30 ms |
| Globex churn rate report | 5 | 1.62 ms |
| headcount in Kazan during 2022 | 5 | 2.23 ms |
| Initech margin units | 5 | 1.95 ms |
| support load Dubai filing | 5 | 1.66 ms |
| Размер хранилища | Время заполнения | Медиана поиска |
|---|---|---|
| 1000 memories | 53 ms | 5.28 ms |
| 5000 memories | 926 ms | 23.52 ms |
| 10000 memories | 828 ms | 47.47 ms |
Сборка дайджеста (релевантное + TODO + недавнее): 4 релевантных воспоминания за 4.76 мс.
Воспроизвести
Benchmarks run on provisioned servers. See the GitHub repository for the benchmark source and reproduction instructions. Numbers above are a snapshot on macOS arm64 (10 cores), release build.
Качество и тестирование
| Метрика | Детали |
|---|---|
| Unit tests | 1000+ tests across 13 workspace crates |
| Property-based testing | proptest for email/phone parsers, SSE parser, absorb pipeline, tokenizer |
| CI-gated benchmarks | Every release must pass performance baselines |
Полевые заметки: 31× на repo_map
Бенчмарки — это как мы ловим регрессии и находим выигрыши. Профилирование repo_map вскрыло молча сериализованный regex-проход; перевод его на кешируемый OnceLock-компилятор сократил время с 902 мс до 29.5 мс (31×). Тот же аудит дал 3.12× / 5.16× на web_feed и code_symbols под execute_batch_spawn.