W jaki sposób aktualizacja jest znacznie szybsza niż wyszukiwanie?

11

Jak to jest updatedbo wiele szybsze niż find?

Oto porównanie czasowe updatedbz findpoleceniem, które wykonuje pozornie podobne zadanie.

porównaj.sh

#!/usr/bin/env bash

cmd="sudo updatedb"
echo $cmd
time eval $cmd

cmd="sudo find / \
    -fstype ext4 \
    -not \( \
        -path '/afs/*' -o \
        -path '/net/*' -o \
        -path '/sfs/*' -o \
        -path '/tmp/*' -o \
        -path '/udev/*' -o \
        -path '/var/cache/*' -o \
        -path '/var/lib/pacman/local/*' -o \
        -path '/var/lock/*' -o \
        -path '/var/run/*' -o \
        -path '/var/spool/*' -o \
        -path '/var/tmp/*' -o \
        -path '/proc/*' \
    \) &>/dev/null"

echo $cmd
time eval $cmd

Mój /etc/updatedb.conf:

PRUNE_BIND_MOUNTS = "yes"
PRUNEFS = "9p afs anon_inodefs auto autofs bdev binfmt_misc cgroup cifs coda configfs cpuset cramfs debugfs devpts devtmpfs ecryptfs exofs ftpfs fuse fuse.encfs fuse.sshfs fusectl gfs gfs2 hugetlbfs inotifyfs iso9660 jffs2 lustre mqueue ncpfs nfs nfs4 nfsd pipefs proc ramfs rootfs rpc_pipefs securityfs selinuxfs sfs shfs smbfs sockfs sshfs sysfs tmpfs ubifs udf usbfs vboxsf"
PRUNENAMES = ".git .hg .svn"
PRUNEPATHS = "/afs /net /sfs /tmp /udev /var/cache /var/lib/pacman/local /var/lock /var/run /var/spool /var/tmp"

Dla polecenia find właśnie podałem ext4system plików, ponieważ jest to jedyny system plików, który updatedbpowinien w końcu przejrzeć. Nie zawracałem sobie głowy rozszerzeniami plików i nie wiem, jak wykluczyć łączenie z wiązania, findale nie mam żadnego. Dodałem także wykluczenie dla „/ proc”, które wydaje się updatedbignorować. Powinienem również zignorować „/ sys”.

Gdyby była jakakolwiek różnica, oczekiwałbym, że polecenie find będzie nieco szybsze, ponieważ jego zasady są nieco prostsze i nie muszą zapisywać na dysk. Zamiast tego updatedbjest znacznie szybszy.

$ ./compare.sh
sudo updatedb

real    0m0.876s
user    0m0.443s
sys 0m0.273s

sudo find / -fstype ext4 -not \( -path '/afs/*' -o -path '/net/*' -o -path '/sfs/*' -o -path '/tmp/*' -o -path '/udev/*' -o -path '/var/cache/*' -o -path '/var/lib/pacman/local/*' -o -path '/var/lock/*' -o -path '/var/run/*' -o -path '/var/spool/*' -o -path '/var/tmp/*' -o -path '/proc/*' \) &>/dev/null

real    6m23.499s
user    0m14.527s
sys 0m10.993s

Co oni robią inaczej?

Prakseolityczny
źródło
użyj, set -xaby włączyć drukowanie poleceń przed ich wykonaniem, więc nie potrzebujesz eval shenanigans.
Peter Cordes,

Odpowiedzi:

15

Zobacz stronę podręcznika, aby zobaczyć updatedb: „Jeśli baza danych już istnieje, jej dane są ponownie wykorzystywane, aby uniknąć ponownego czytania katalogów, które nie uległy zmianie”.

Natomiast findpolecenie przechodzi przez wszystkie katalogi bez względu na to, czy uległy zmianie.

Steve
źródło
1
Jak można to sprawdzić: stackoverflow.com/questions/3620684/…
Praxeolitic