Аналіз Rust-аналогів CLI-утиліт

Вступ

Привіт! Мене звати Андрій, я навчаюсь в 11 класі та у вільний час навчаюсь програмуванню. Мій шлях почався з Java та Go, де я створював невеликі pet-проєкти й поступово долучався до open-source.

Зараз активно вивчаю Rust, і для практики вирішив переписати відому CLI-утиліту f3 з мови C. У репозиторії вже є робоча версія, але попереду ще чимало роботи — зокрема написання тестів для перевірки сумісності з оригінальною f3

NeoF3 в Github: клік

Також мені цікаво дослідити інші CLI-інструменти на Rust та порівняти їх з класичними аналогами на C: де вони швидші, де зручніші, а де надійніші. Саме цьому присвячена ця стаття.

hyperfine — утиліта для бенчмарків CLI

Перша утиліта в цьому артиклі, адже її я буду використовувати в усіх порівняльних бенчмарках.
hyperfine — це сучасний інструмент для порівняння швидкодії команд у терміналі.
Він автоматично виконує багато запусків, рахує середнє значення, стандартне відхилення, будує діапазон і одразу показує результат у зручному форматі.
Тестове середовище: x86_64 Linux 6.16.3-arch1-1, CPU: Intel Core i5-11400H, GPU: NVIDIA GeForce RTX 3050 Ti, RAM: 15764MiB DDR4.

Основні фічі hyperfine

  • Простота: підтримка довільних команд (будь-яка CLI-команда може бути протестована).
  • Прогрів (warmup runs): кілька «розігрівочних» ітерацій перед основними вимірюваннями.
  • Постійний фідбек: прогрес, ETA і проміжні оцінки.
  • Відсікання аномалій: автоматично визначає статистичні викиди.
  • Експорт результатів: CSV, JSON, Markdown, AsciiDoc.
  • Кросплатформеність: Linux, macOS і Windows.
  • Зручна візуалізація: ASCII-таблиці, кольоровий вивід.

Demo: Benchmarking fd і find

hyprfine

zoxide

zoxide — це розумна заміна стандартній команді cd, яка за допомогою алгоритму обліку частоти та свіжості відвідувань розуміє, куди користувач хоче перейти.

⚙️ Алгоритм роботи

З кожним переходом в одну й ту ж директорію її score збільшується на +1 у локальній БД. Після кожного запиту розраховується frecency за таким принципом:

Last access time

├── Within the last hour score * 4
├── Within the last day score * 2
├── Within the last week score / 2
└── Otherwise score / 4 

⏳ Старіння даних

При досягненні кількості записів у БД = _ZO_MAXAGE, всі score діляться на певне k, внаслідок чого загальний рейтинг стає приблизно 90% від _ZO_MAXAGE. Це не дає базі рости нескінченно

📥 Інсталяція

Для інтеграції, zoxide потрібно додати спеціальну команду у конфігурацію вашого shell. Наприклад, для fish:

zoxide init fish | source

Додайте цей рядок у кінець файлу:
~/.config/fish/config.fish

⚠️ Додаткові прапорці також слід вказувати у цьому рядку (наприклад, власний псевдонім команди).

Demo: zoxide

zoxide demo

ripgrep — сучасний аналог grep

ripgrep (далі rg) — сучасний аналог класичної grep, написаної на C.

Переваги rg над grep

  • Багатопотокове виконання: значно прискорює пошук.
  • Автоматичний фільтр: враховує .gitignore, .ignore, .rgignore; ігнорує приховані та бінарні файли (можна вимкнути -uuu).
  • Рекурсія з коробки: не потребує додаткових прапорців.
  • Rust regex engine: гарантує лінійний час, безпечний щодо пам’яті, уникає катастрофічного бек-трекінгу.
  • Підтримка заміни знайдених даних.
  • Загалом інтерфейс більш дружній та зручний.

Demo: ripgrep

ripgrep demo

Benchmark: rg vs grep

Тест на локальному проєкті (пошук сигнатур функцій у Rust-коді):
❯ hyperfine -w 3 -r 10 -N \
’rg "fn\s+[a-z_]+\("’ \
’grep -RE "fn\s+[a-z_]+\(«
Benchmark 1: rg "fn\s+[a-z_]+\("
Time (mean ± σ): 4.1 ms ± 0.5 ms [User: 1.6 ms, System: 2.4 ms]
Range (min … max): 3.7 ms … 5.0 ms 10 runs
Benchmark 2: grep -RE "fn\s+[a-z_]+\("
Time (mean ± σ): 2.151 s ± 0.009 s [User: 1.886 s, System: 0.264 s]
Range (min … max): 2.131 s … 2.160 s 10 runs
Summary
rg "fn\s+[a-z_]+\(" ran
519.67 ± 59.60 times faster than grep -RE "fn\s+[a-z_]+\("

bat — клон cat з підсвіткою синтаксису

bat — це «красивий клон» cat з підсвіткою синтаксису та Git-інтеграцією. Якщо ж перенаправити результат у файл або пайп, bat поводитиметься як звичайний cat.

Основні фічі bat

  • Підсвітка синтаксису (визначається за розширенням файлу).
  • Відображення назви файлу та номерів рядків.
  • Інтеграція з Git (modified/added/deleted).
  • Автоматичний пейджинг через less (можна вимкнути —paging=never).
  • Режим непринтованих символів (-A): таби, пробіли, переноси рядків,
    Інтеграція з іншими тулзами.

⚠️ Продуктивність: у середньому bat працює у ~8 разів повільніше за cat через обробку в user-space.

Demo: bat

bat demo

Benchmarks: bat vs cat

Тест 1. «Сирі» виклики на main.rs (15 kB):
❯ hyperfine -w 3 -r 10 -N ’bat main.rs’ ’cat main.rs’
Benchmark 1: bat main.rs
Time (mean ± σ): 3.3 ms ± 0.1 ms [User: 1.8 ms, System: 1.4 ms]
Benchmark 2: cat main.rs
Time (mean ± σ): 405.7 µs ± 29.2 µs [User: 249.6 µs, System: 112.2 µs]
Summary
cat main.rs ran 8.22 ± 0.62 times faster than bat main.rs
Тест 2. «Максимально схожий на cat» режим bat:
❯ hyperfine -w 3 -r 10 -N \
’bat —paging=never —color=never main.rs’ \
’cat main.rs’
Benchmark 1: bat --paging=never --color=never main.rs
Time (mean ± σ): 3.4 ms ± 0.2 ms [User: 1.1 ms, System: 2.2 ms]
Benchmark 2: cat main.rs
Time (mean ± σ): 410.6 µs ± 43.2 µs [User: 323.5 µs, System: 39.1 µs]
Summary
cat main.rs ran 8.17 ± 0.94 times faster than bat --paging=never --color=never
👉 У реальному використанні різниця у 3–4 мс проти ~0.4 мс на файлі 15kB — дрібниця. А от додатковий функціонал bat робить навігацію та читання коду значно зручнішими.

just — зручний раннер команд у проєкті

Переваги just над make

  • just — це не build-система, а простий раннер команд, що уникає складностей make.
  • Кросплатформеність: Linux, macOS, Windows.
  • Парсинг аргументів з командного рядка:
build target:
@echo ’Building {{target}}...’
cd {{target}} && make
Виклик:
❯ just build my-awesome-project
Building my-awesome-project...
cd my-awesome-project && make
  • Парсинг .env: dotenv-* опції.
  • Recipes будь-якою мовою; можна викликати з піддиректорій.

Demo: just

demo just

Benchmarks: just vs make

📌 Маленькі локальні recepies
❯ hyperfine -w 3 -r 30 ’just default’ ’make default’
Benchmark 1: just default ~2.7 ms
Benchmark 2: make default ~1.4 m
Summary: make default ran ~1.8× faster

❯ hyperfine -w 3 -r 30 'just echo-task' 'make echo-task'
Benchmark 1: just echo-task ~2.6 ms
Benchmark 2: make echo-task ~3.2 ms
Summary: just echo-task ran ~1.2× faster

❯ hyperfine -w 3 -r 30 'just tiny-loop' 'make tiny-loop'
Benchmark 1: just tiny-loop ~2.6 ms
Benchmark 2: make tiny-loop ~3.0 ms
Summary: just tiny-loop ran ~1.1x faster

📌 Великі цільові задачі (реальний проєкт)

❯ hyperfine -w 3 -r 10 ’just read_test’ ’make read_test’
Benchmark 1: just read_test ~88.4 ms
Benchmark 2: make read_test ~88.2 ms
Summary: майже однаково швидко

fd — сучасна альтернатива find із лаконічним синтаксисом і підсвічуванням результатів.

Основні фічі fd

  • Швидкість: багатопоточний пошук.
  • Простий синтаксис.
  • Автоматичні ігнори (.gitignore тощо).
  • Smart case.
  • Пошук за розширенням або типом.
  • Rust regex замість shell glob.

Demo

fd demo

Benchmarks: fd vs find

Пошук файлу main.rs:
❯ hyperfine -w 3 -r 10 -N \
’fd -H main.rs’ \
’find . -name main.rs’
Benchmark 1: fd -H main.rs
Time (mean ± σ): 233.9 ms ± 3.5 ms [User: 1155.3 ms, System: 1128.6 ms]
Range (min … max): 230.5 ms … 239.6 ms 10 runs
Benchmark 2: find . -name main.rs
Time (mean ± σ): 794.6 ms ± 9.7 ms [User: 261.7 ms, System: 532.7 ms]
Range (min … max): 774.1 ms … 808.1 ms 10 runs
Summary
fd -H main.rs ran
3.40 ± 0.07 times faster than find . -name main.rs

eza — сучасна альтернатива ls

eza — покращена версія ls з Git-інтеграцією, tree-режимом, іконками, SELinux-контекстом і strcustom themes.
⚠️ За додаткову функціональність доводиться платити швидкістю — eza повільніший за ls, але у реальних умовах це майже непомітно.

Demo: eza

eza demo

Benchmarks: eza vs ls

❯ hyperfine -w 3 -r 10 ’dust’ ’du'
Benchmark 1: dust
Time (mean ± σ): 111.6 ms ± 4.2 ms [User: 227.9 ms, System: 499.5 ms]
Range (min … max): 104.3 ms … 120.8 ms 10 runs
Benchmark 2: du
Time (mean ± σ): 260.8 ms ± 6.4 ms [User: 45.1 ms, System: 211.8 ms]
Range (min … max): 252.8 ms … 271.1 ms 10 runs
Summary
dust ran
2.34 ± 0.11 times faster than du

dust — більш інтуїтивна альтернатива du

dust робить оцінку використання дискового простору наочною завдяки ASCII-графікам і сортуванню.

Найкорисніші фічі dust

  • -d N : обмеження глибини дерева.
  • -n K : топ-K директорій/файлів.
  • -D/-F : лише директорії / лише файли.
  • -z SIZE : мінімальний розмір для виводу.
  • -e regex/-v regex : включити/виключити за патерном.
  • -t : групування за типом файлів.
  • -p : повні шляхи.
  • -x : в межах файлової системи.
  • -j : JSON-вивід.
  • —collapse=DIR : згортати «шумні» каталоги.

Demo: dust

dust demo

Benchmark: dust vs du

❯ hyperfine -w 3 -r 10 \ ’dust’ \ ’du’ 
Benchmark 1: dust
Time (mean ± σ): 111.6 ms ± 4.2 ms [User: 227.9 ms, System: 499.5 ms]
Range (min … max): 104.3 ms … 120.8 ms 10 runs
Benchmark 2: du
Time (mean ± σ): 260.8 ms ± 6.4 ms [User: 45.1 ms, System: 211.8 ms]
Range (min … max): 252.8 ms … 271.1 ms 10 runs
Summary
dust ran
2.34 ± 0.11 times faster than du

procs — сучасна альтернатива ps, написана на Rust

Основні переваги procs

  • Кольоровий вивід.
  • Додаткова інформація: TCP/UDP порти, IO-швидкості, Docker-ім’я, статистика пам’яті.
  • Вбудований пейджер.
  • Фільтрація без grep (логічні оператори).
  • Сортування (—sortd, —sorta).
  • Watch-режим (—watch).
  • SON-вивід для інтеграцій.

Недоліки procs

  • Можливі глюки відображення у деяких терміналах.
  • Обмеженість у виборі колонок (одна через —only порівняно з гнучким ps).
  • Продуктивність: повільніший за ps приблизно в 13 разів.

procs demo

Benchmark: procs vs ps

❯ hyperfine -w 3 -r 10 \
’procs —color=disable —no-header —only command’ \
’ps -eo command —no-headers’ 
Benchmark 1: procs --color=disable --no-header --only command
Time (mean ± σ): 118.0 ms ± 1.0 ms [User: 7.2 ms, System: 10.2 ms]
Range (min … max): 117.2 ms … 120.6 ms 10 runs
Benchmark 2: ps -eo command --no-headers
Time (mean ± σ): 9.3 ms ± 0.8 ms [User: 3.6 ms, System: 5.3 ms]
Range (min … max): 8.7 ms … 11.4 ms 10 runs
Summary
ps -eo command --no-headers ran
12.65 ± 1.06 times faster than procs --color=disable --no-header --only command
👉 procs залишив не дуже приємні емоції через баги виводу, але він зручніший та інформативніший для щоденного використання, якщо його налагодити.

tealdeer — надшвидка версія tldr на Rust

tealdeer генерує зручні для читання manual pages для будь-якої утиліти. Сучасна альтернатива tldr з такими покращеннями:
  • Швидкість: майже в 60x швидше.
  • Кешування: перший виклик завантажує і кешує всю базу tldr pages, працює офлайн.
  • Документація: зручний онлайн-підручник.
  • Кастомізація: можна гнучко налаштовувати клієнт.

Demo: tealdeer

tealdeer demo

Benchmark: tealdeer vs tldr

Порівняння програм з отриманням мануалів 15 утиліт, записаними в vars.txt
hyperfine -w 3 -r 5 -c —shell=none -L util «$(paste -sd, vars.txt)» \
’tealdeer {util}’ \
’tldr -k {util}’
Summary
tealdeer curl -c ran
57.5 ± 6.7 times faster than tldr -k
Порівняння програм з отриманням мануалів 1 утиліті
hyperfine —shell=none -w 3 -r 10 \
’tealdeer make -c’ \
’tldr -k make’
Benchmark 1: tealdeer make -c
Time (mean ± σ): 1.1 ms ± 0.1 ms [User: 0.3 ms, System: 0.7 ms]
Range (min … max): 1.0 ms … 1.2 ms 10 runs
Benchmark 2: tldr -k make
Time (mean ± σ): 62.1 ms ± 2.9 ms [User: 51.2 ms, System: 8.1 ms]
Range (min … max): 59.0 ms … 65.6 ms 10 runs
Summary
tealdeer make -c ran
57.57 ± 5.35 times faster than tldr -k make

Висновки

Rust-екосистема CLI-утиліт сьогодні виглядає як повноцінна альтернатива класичним С-шним інструментам. Більшість із них не просто повторюють функціонал оригіналів, а й приносять відчутну цінність:
  • ergonomics — простіший синтаксис, зручніші прапорці;
  • UX — кольори, підсвітка, інтеграція з Git, вбудовані пейджери;
  • performance — часто Rust-версії швидші (fd, ripgrep, dust), хоча деякі (procs, bat, eza) мають невеликий оверхед;
  • кросплатформеність і активна підтримка ком’юніті.
Принцип: якщо важлива швидкість системних скриптів, класика ще довго буде незамінною.
Якщо ж ви щодня працюєте у терміналі й хочете комфорт і можливості — Rust CLI — must-have.
Ми спостерігаємо «другу молодість» терміналу: спільнота Rust поєднує UNIX-філософію з сучасним девелоперським досвідом. А ви вже пробували перейти з cd на zoxide або з grep на ripgrep? 😉

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

👍ПодобаєтьсяСподобалось5
До обраногоВ обраному3
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

З переліченого нічим не користуюсь, бо наприклад підсвітку синтаксису той bat зробить чи ні залежить від налаштувань терміналу, затягувати ту нестандартні тулзи в наприклад докер чи тим більше на ембеддед залізяку ніхто не буде, на рандомній машині може не бути прав на довстановлення нестандартних пакетів, а виграш у більшості випадків сумнівний.
Коли раз в півроку доводиться грепати щось дуже велике, то LC_ALL=C grep -rnF ... все одно упирається навіть одним своїм потоком у i/o.

Для популяризації расту краще рекламувати не маючі аналогів тулзи, типу ncdu для перегляду зайнятого місця на диску, чи krokiet для пошуку дублів медіафайлів.

Більшість з наведених тут fancy команд трохи використовував колись для ознайомлення, а потім повертався до звичних без сюрпрайзів. Grep/rg порівняння я би сказав що не зовсім коректне (бо лімітований пошук і має бути більш швидким по дефолту). Єдину з означених яку зараз використовую то just, і не як заміну make, а як додаткову тулзу для мінімально простих команд (а якщо порівнювати build tools перфоманс — то треба булоб брати ninja в рамках cmake чи meson які більш актуальні на сьогодні ніж autotools way).

p.s. плюс в статті бачу трохи в іншому (не в fancy командах) — у використанні стат.тулзи для бенчмарків виконання команд (про що часто забувають, а тут з цим все ок)

Нещодавно перейшов з grep на rg. Працює швидше, не перевіряє файли з node_modules, і т.д. Різниця присутня і позитивна

людський сексі топік про раст, але в чому сенс тоді виключно раст-аналогів?

я б додав ще argc для випадків коли just задовбує, та uv

Підписатись на коментарі