2015-04-21 5 views
-1

Руководство Debian's Bash предлагает использовать специальную подстановку команд $(< file), если для обеспечения производительности требуется $(cat file), избегая выполнения внешнего двоичного файла.

Однако, измеренное время завершения следующего кода примерно такая же:

time for i in {0..1000}; do echo str | { in=$(cat); }; done 
time for i in {0..1000}; do echo str | { in=$(< /dev/fd/0); }; done 

За несколько прогонов, они последовательно возвращают значения вокруг этих цифр, соответственно:

real 0m3.665s 
user 0m0.365s 
sys  0m0.782s 

и

real 0m2.401s 
user 0m0.233s 
sys  0m0.533s 

Таким образом, улучшение замены команд над cat в значительной степени незначительна для большинства случаев использования. Поскольку мой скрипт должен быстро и циклично читать большое количество stdin, что я могу сделать, чтобы ускорить эти чтения? В частности, весь поток данных stdin необходимо сбрасывать в переменную Bash для дальнейших подстановок .

Дальнейшие испытания:

После комментариев ниже и дальнейшего тестирования, я поставил 10000 итераций вместо 1000 , чтобы свести к минимуму установка трубы над головой, и я удалил скобки для команды синтаксиса соединения:

$ time for i in {1..10000}; do echo str | in=$(cat); done 

real 0m24.754s 
user 0m6.958s 
sys  0m18.996s 

$ time for i in {1..10000}; do echo str | in=$(< /dev/fd/0); done 

real 0m33.913s 
user 0m3.736s 
sys  0m10.516s 

Здесь я не могу объяснить, почему $(< /dev/fd/0) еще медленнее в настоящее время.

+3

Я смущен. Ваш тест показывает ускорение на 33%. –

+0

... и этот быстрый тест в значительной степени измеряет время, необходимое для настройки трубопровода, в отличие от производительности чтения stdin. Возможно, если вы указали нам свой * фактический * код, мы могли бы попытаться помочь с его оптимизацией, но, как бы то ни было, цифры, которые вы видите, выглядят в высшей степени разумными. –

+0

Для интегрированного вызова Bash я ожидал чего-то в значительной степени ниже миллисекунды. – davide

ответ

3

Вы забываете учитывать издержки производительности, не связанные с чтением из stdin (затраты на fork() для создания подоболочки, настройку конвейера, wait() для выхода этих процессов и т. Д.).

$ time for i in {0..1000}; do echo str | { in=$(cat); }; done 
real 0m3.183s 
user 0m1.427s 
sys  0m2.486s 

$ time for i in {0..1000}; do echo str | { in=$(< /dev/fd/0); }; done 
real 0m1.973s 
user 0m0.917s 
sys  0m1.844s 

$ time for i in {0..1000}; do echo str | true; done 
real 0m1.294s 
user 0m0.708s 
sys  0m1.367s 

Таким образом:

  • Использование $(cat) добавляет приблизительно (3.183s - 1.294s == 1.889s) время от стены часы более 1000 итераций, по сравнению с кодом, который делает все другие настройки, но Безразлично» t читать stdin.
  • Использование $(</dev/fd/0) добавляет приблизительно (1.972 с - 1.294s == 0.697s) более 1000 итераций.

Это улучшение в 2,7 раза, и вы можете рассчитывать на 1 мс за вызов.