[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [HS] un filtre 'find alike'



hello,

> >    une commande | while read p; do
> >      test -f $p && echo $p
> >    done

> > mais c'est chiant à écrire
> Je te l'accorde...

bon réellement j'ai dans mon .zshenv:

  '?-' () while {read it} {"$@" $it && print $it}

du coup en vrai j'écris

  une commande |\?- test -f

mais si j'écris un script pour les collègues, je me force à ne pas
utiliser ce genre de shortcuts

> > et pas super efficace sur de grosses listes

> ... tu es sûr de ça ? J'ai un doute, parce que "while" est un mot clé,
> "read" et "test" sont built-in.

d'experience, il n'y a pas photo: les filtres sont toujours plus
performants que les while loops.

d'un autre coté: j'ai acquis cette conviction il y a fort longtemps
(fin du millénaire dernier ) sans actualiser ni approffondir ...
alors j'ai fais un benchmark au doigt mouillé (le script ci-apres) qui
me permet de confirmer ...

sachant que:

* bash n'est pas présent dans le test parceque:
  * c'est un shell que je n'utilise pas
  * j'ai fais le test sur une box openbsd pour avoir xargs -J
* je n'ai même pas essayé avec xargs -I ... ce sera forcément tristoune
* zsh fait un bien mauvais score: je note mais ca n'est pas le sujet
  alors je n'ai pas cherché à savoir si c'était perfectible
* perl forever \o/

shell	user	kernel	elapsed
ksh	0.75s	0.57s	1.33s
zsh	2.77s	4.97s	7.73s
sh	0.80s	0.53s	1.33s
xargs	0.13s	0.61s	0.74s
perl	0.07s	0.37s	0.44s

le script en question:

  # creer un jeu de données

  find . >     sep---
  cat          sep---{,,,,,,,,,,,} > sep-0a
  tr '\n' '\0' < sep-0a > sep-00
  times=5

  # lire le jeu une premiere fois histoire d'etre fair play
  cat sep* > /dev/null

  # while loop
  script='
    while read it; do
      test -f "$it" && echo "$it"
    done > /dev/null
  '

  print shell user kernel elapsed

  for shell (ksh zsh sh) {
    TIMEFMT="$shell %U %S %E"
    < sep-0a time $shell -c $script
  }

  TIMEFMT="xargs %U %S %E"
  < sep-00 time sh -c 'xargs -0 -J %  find % -prune -type f > /dev/null 2>&1'

  TIMEFMT="perl %U %S %E"
  < sep-0a time sh -c ' perl -lne"print if -f" > /dev/null 2>&1 '


Reply to: