Skip to content

Свёртка тяжёлых каталогов: анализ вдвое быстрее, а объём тот же до байта - #1

Merged
the-homeless-god merged 2 commits into
masterfrom
a/fold-heavy-dirs
Sep 4, 2026
Merged

the-homeless-god merged 2 commits into
masterfrom
a/fold-heavy-dirs

Conversation

@the-homeless-god

Copy link
Copy Markdown
Member

Владелец: «надо бы сделать так, чтобы он умел быстро тоже анализировать например в папке node_modules, pycache, чтобы оч долго их не исследовал».

Замер, с которого всё началось

Дерево портала courses, 82 923 записи, 1,4 ГБ:

обход без решающего слоя 0,81 с
обход с решающим слоем на flang 17,5 с
из них один node_modules (50 384 записи) 9,9 с

Девять десятых времени уходит не на чтение диска, а на пятьдесят тысяч отдельных приговоров о файлах внутри каталога, который человек удаляет целиком или не трогает вовсе.

Что изменилось

было стало
время 17,3 с 8,3 с
записей 82 923 82 923
файлов 60 620 60 620
объём 3 575 583 843 Б 3 575 583 843 Б

Свёртка не пропускает каталог: байты сосчитаны все, TotalBytes сходится с du -sb, жёсткие ссылки считаются один раз, корзины по разряду и приговору по-прежнему сходятся с итогом. Дешевеет только приговор — он выносится один раз, о самом каталоге, и им заряжается поддерево.

В «крупнейших» теперь стоит node_modules — 1,2 ГиБ вместо отдельного файла внутри него, а отчёт называет свёрнутое поимённо.

Список имён

node_modules, __pycache__, .mypy_cache, .pytest_cache, .ruff_cache, .gradle, .tox, .next, .nuxt, .turbo, .parcel-cache, .svelte-kit — у каждого записана причина.

Намеренно нет build, dist, target и venv: первые три — обычные имена рабочих каталогов, а venv слишком часто зовут иначе. Их свернуло бы имя, а не природа.

--no-fold возвращает прежнее поведение целиком.

Проверки

go test ./... и go vet зелёные. Тест несёт отрицательный контроль в себе: счётчик решений без свёртки обязан быть больше, иначе тест не отличил бы свёртку от пустого дерева. Ключ описан в справке и в обеих man-страницах — этого потребовали сторожа, которые уже стояли.

the-homeless-god added 2 commits September 4, 2026 11:38
…десятью тысячами приговоров

Владелец: «надо бы сделать так, чтобы он умел быстро тоже анализировать
например в папке node_modules, pycache, чтобы оч долго их не исследовал».

ЗАМЕР, С КОТОРОГО ВСЁ НАЧАЛОСЬ. Дерево портала courses, 82 923 записи,
1,4 ГБ:

  обход без решающего слоя          0,81 с
  обход с решающим слоем на flang  17,5 с
  из них один node_modules          9,9 с (50 384 записи)

Девять десятых времени уходит не на чтение диска, а на то, чтобы вынести
пятьдесят тысяч отдельных приговоров о файлах внутри каталога, который
человек удаляет целиком или не трогает вовсе.

ЧТО СДЕЛАНО. У обхода появилась свёртка (scan.Options.Fold): каталог из
списка имён считается целиком — решающий слой спрашивают ОДИН раз, о нём
самом, и его приговором заряжается всё поддерево.

Стало 8,3 с против 17,3 с. При этом:

  записей   82 923 против 82 923   совпало
  файлов    60 620 против 60 620   совпало
  объём     3 575 583 843 байта    совпало до байта
  корзины по разряду и приговору по-прежнему сходятся с итогом

Свёртка НЕ пропускает каталог. Байты сосчитаны все, TotalBytes сходится
с `du -sb`, жёсткие ссылки считаются один раз. Пропуск — это `--exclude`
у чужих чистильщиков, и он врёт о размере; здесь дешевеет только
приговор.

Человеку от этого лучше вдвойне: в «крупнейших» теперь стоит
`node_modules — 1,2 ГиБ`, а не отдельный файл внутри него. Отчёт
называет свёрнутое поимённо: «свёрнуто каталогов 1, записей в них
50 383 (1,2 ГиБ): сосчитаны все, приговор один на каталог».

СПИСОК ИМЁН строгий, с причиной у каждого: node_modules, __pycache__,
.mypy_cache, .pytest_cache, .ruff_cache, .gradle, .tox, .next, .nuxt,
.turbo, .parcel-cache, .svelte-kit. Здесь намеренно нет «build», «dist»,
«target» и «venv»: первые три — обычные имена рабочих каталогов, а
«venv» слишком часто зовут иначе. Их свернуло бы имя, а не природа.

Кому нужна подробность внутри — «--no-fold», и прежнее поведение
возвращается целиком (проверено: итог и число записей те же).

Тест несёт отрицательный контроль в себе: тот же счётчик решений на том
же дереве без свёртки обязан быть больше — иначе тест не отличил бы
свёртку от пустого дерева. Он же поймал мою арифметику: я написал в
ожиданиях 4 записи вместо пяти.

go test ./... и go vet зелёные; ключ описан в справке и в обеих
man-страницах — этого потребовали сторожа, которые уже стояли.
Выпуск ради одного умения, зато того, которое человек замечает первым:
`digitdisk analyze` на дереве с node_modules идёт 8,3 секунды вместо
17,3 — и показывает `node_modules — 1,2 ГиБ` одной строкой вместо файла
внутри него.

Патч, а не минор: поверхность инструмента не изменилась, ключей стало
на один больше (`--no-fold`), а числа отчёта остались прежними до байта.

Владелец просил «бампни на 0.8.x»; в стволе на GitHub уже 0.9.0 —
локальное зеркало /home/b/projects/digitdisk отстало на пять коммитов,
и я собирал ветку от него. Ветка перебазирована на настоящий ствол,
номер взят от него же.
@the-homeless-god
the-homeless-god merged commit b401147 into master Sep 4, 2026
0 of 6 checks passed
@the-homeless-god
the-homeless-god deleted the a/fold-heavy-dirs branch September 4, 2026 11:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant