Несмотря на то, что bash действительно является неподходящим инструментом для работы (связанные списки ... см. Комментарии выше), все еще возможно сделать это с приемлемой производительностью, используя coproc и shuf -r
.
Немногосложный пример, требует $a
сверху:
(
coproc rid {
for e in "${a[@]}"; do
echo "$e";
done | shuf -r;
};
seq 150000 \
| while read s; do
for i in {1..10}; do
read -u ${rid[0]} a;
s="$s:$a";
done;
echo "$s";
done
) | pv -ls 150000 >/dev/null
-
-r
получает shuf
, чтобы не перемешивать, а просто выплевывать случайные элементы без запоминания бесконечно. - Внешний
( )
необходим, потому что я хотел, чтобы выход цикла перешел на pv
для измерения.Это показывает, что у меня есть проблема с этим решением: я не думаю, что coprocs просты в использовании, так как вы не можете прочитать их вывод из подоболочки, и вам нужно подумать о том, как завершить их корректно.shopt -s lastpipe
может помочь с некоторыми проблемами.
В целом, это примерно в 200 раз быстрее, чем оригинальная версия (примите это с более чем одним зерном соли), но, конечно, все ещеаналогичный фактор медленнее, чем оптимизированная нативная реализация.