Hodiaŭ ni volas paroli pri kelkaj el la plej novaj ĝisdatigoj al la Sherlock-sistemo [ĉi tio estas alt-efikeca areto en Universitato Stanford - ĉ. trans.], kiu signife plirapidigas listigon de dosieroj en dosierujoj kun granda nombro da enskriboj.
Male al regulaj artikoloj, ĉi tio estas pli de interna raporto pri kiel ni regule laboras pri Sherlock por ke ĝi funkcias plej bone por niaj uzantoj. Ni esperas publikigi pli da tiaj artikoloj estonte.
Listigi multajn dosierojn bezonas tempon
Ĉio komenciĝis per teknika subtena demando de uzanto. Li raportis la problemon, ke la ekzekuto ls
prenas kelkajn minutojn en dosierujo kun pli ol 15 enskriboj $SCRATCH
[dosierujo por provizoraj dosieroj - ĉ. leno].
Miloj da dosieroj en unu dosierujo kutime prezentas ŝarĝon al la dosiersistemo kaj certe ne estas rekomenditaj. La uzanto sciis ĉi tion kaj konfesis, ke ĝi ne estas bona, sed menciis, ke la listo estis 1000 fojojn pli rapida en sia tekkomputilo ol Sherlock. Kompreneble, ĉi tio doloris nin. Do ni rigardis pli profunde.
Ĉar ls aspektas bela
Ni rigardis kion ĝi efektive faras ls
kiam listigas dosierujon, kaj kial la procezo daŭras tiel longe. Sur plej modernaj distribuoj ls
defaŭlte ĝi funkcias kiel ls --color=auto
, ĉar ĉiuj ŝatas la kolorojn.
Sed belaj koloroj havas prezon: por ĉiu dosiero ls
devas akiri informojn pri la dosiertipo, ĝiaj permesoj, flagoj, etenditaj atributoj kaj similaj por elekti la taŭgan koloron.
Unu simpla solvo al la problemo estas tute malŝalti koloron en ls, sed imagu la indignon de uzantoj. Neniam vi forprenu la kolorproduktaĵon, ni ne estas monstroj.
Do ni rigardis pli profunde. ls
koloraj eniroj per mediovariablo LS_COLORS
, kiu estas fiksita dircolors(1)
surbaze de agorda dosiero dir_colors(5)
. Jes,
Ni rigardu pli detale
Por determini kiu kolorskemo kaŭzas la malrapidiĝon, ni kreis eksperimentan medion:
$ mkdir $SCRATCH/dont
$ touch $SCRATCH/dont/{1..10000} # don't try this at home!
$ time ls --color=always $SCRATCH/dont | wc -l
10000
real 0m12.758s
user 0m0.104s
sys 0m0.699s
12,7 sekundoj por 10 dosieroj, ne tre bona.
Cetere, ni bezonas flagon
--color=always
: kvankam li turnas sin alls --color=auto
, sedls
detektas kiam ĝi ne estas konektita al terminalo (ekz. per pipo aŭ kun eliga redirekto) kaj malŝaltas kolorigon se agordita alauto
. Saĝa ulo.
Kio do daŭras tiel longe? Ni rigardis kun strace
:
$ strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
44.21 0.186617 19 10000 lstat
42.60 0.179807 18 10000 10000 getxattr
12.19 0.051438 5 10000 capget
0.71 0.003002 38 80 getdents
0.07 0.000305 10 30 mmap
0.05 0.000217 12 18 mprotect
0.03 0.000135 14 10 read
0.03 0.000123 11 11 open
0.02 0.000082 6 14 close
[...]
Wow: 10 vokoj lstat()
, 10 vokoj getxattr()
(kiuj ĉiuj malsukcesas ĉar nia medio ne havas la atributojn, kiujn ls serĉas), 10 vokoj capget()
.
Verŝajne ĉi tio povas esti optimumigita.
Kapabloj atributo? Ne
Sekva konsilo
$ eval $(dircolors -b | sed s/ca=[^:]*:/ca=:/)
$ time strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
98.95 0.423443 42 10000 lstat
0.78 0.003353 42 80 getdents
0.04 0.000188 10 18 mprotect
0.04 0.000181 6 30 mmap
0.02 0.000085 9 10 read
0.02 0.000084 28 3 mremap
0.02 0.000077 7 11 open
0.02 0.000066 5 14 close
[...]
------ ----------- ----------- --------- --------- ----------------
100.00 0.427920 10221 6 total
real 0m8.160s
user 0m0.115s
sys 0m0.961s
Ve, ĝis 8 sekundoj da akcelo! Ni forigis ĉiujn tiujn multekostajn vokojn getxattr()
, kaj defioj capget()
malaperis ankaŭ, bonega.
Sed ankoraŭ ekzistas ĉi tiuj ĝenaj vokoj lstat()
, Kvankam…
Kiom da floroj vi bezonas?
Tial ni rigardis pli detale LS_COLORS
.
Unue ni simple malŝaltis ĉi tiun variablon:
$ echo $LS_COLORS rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36: $ unset LS_COLORS $ echo $LS_COLORS $ time ls --color=always $SCRATCH/dont | wc -l 10000 real 0m13.037s user 0m0.077s sys 0m1.092s
Kio!?! Ĉu ankoraŭ 13 sekundoj?
Rezultas, ke kiam la medio variablo LS_COLORS
nur unu el ĝiaj elementoj ne estas difinita aŭ mankas <type>=color:
, ĝi uzas la enkonstruitan datumbazon defaŭlte kaj ankoraŭ uzas kolorojn. Do se vi volas malŝalti kolorigon por certa dosiertipo, vi devas anstataŭi ĝin per <type>=:
aŭ <type> 00
en dosiero DIR_COLORS
.
Post multe da provo kaj eraro, ni malvastigis nian serĉon al ĉi tio:
EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00
kiu estas skribita kiel
LS_COLORS='ex=00:su=00:sg=00:ca=00:'
Ĉi tio signifas: ne kolorigu dosierojn laŭ atributo.
, nek de
Ni rapidigas ls
Kaj se vi ne faras iun el ĉi tiuj kontroloj, tiam vokas lstat()
malaperu, kaj nun estas tute alia afero:
$ export LS_COLORS='ex=00:su=00:sg=00:ca=00:'
$ time strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
63.02 0.002865 36 80 getdents
8.10 0.000368 12 30 mmap
5.72 0.000260 14 18 mprotect
3.72 0.000169 15 11 open
2.79 0.000127 13 10 read
[...]
------ ----------- ----------- --------- --------- ----------------
100.00 0.004546 221 6 total
real 0m0.337s
user 0m0.032s
sys 0m0.029s
0,3 sekundoj en listo de 10 dosieroj, rekordo.
Starigante Sherlock
De 13 sekundoj kun defaŭltaj agordoj ĝis 0,3 sekundoj kun etaj alĝustigoj LS_COLORS
signifas 40-oblan akcelon pro la foresto setuid
/ setgid
kaj koloraj ruleblaj dosieroj. Ne tiom granda perdo.
Kompreneble, ĉi tio nun estas agordita en Sherlock por ĉiu uzanto.
Sed se vi volas redoni la kolorigon, vi povas simple reveni al la defaŭltaj agordoj:
$ unset LS_COLORS
Sed tiam ĉe dosierujoj kun multaj dosieroj, nepre preparu kafon dum ĝi funkcias ls
.
fonto: www.habr.com