Existe alguma diferença usando pipes?

1

Usando o Ubuntu 12.04.

Usando canos (5 vezes):

$ time echo XYZ | sed 's/X/A/g' | sed 's/Y/B/g' | sed 's/Z/C/g'
ABC

real    0m0.005s
user    0m0.000s
sys 0m0.000s
$ time echo XYZ | sed 's/X/A/g' | sed 's/Y/B/g' | sed 's/Z/C/g'
ABC

real    0m0.004s
user    0m0.000s
sys 0m0.000s
$ time echo XYZ | sed 's/X/A/g' | sed 's/Y/B/g' | sed 's/Z/C/g'
ABC

real    0m0.004s
user    0m0.004s
sys 0m0.000s
$ time echo XYZ | sed 's/X/A/g' | sed 's/Y/B/g' | sed 's/Z/C/g'
ABC

real    0m0.005s
user    0m0.000s
sys 0m0.000s
$ time echo XYZ | sed 's/X/A/g' | sed 's/Y/B/g' | sed 's/Z/C/g'
ABC

real    0m0.005s
user    0m0.004s
sys 0m0.000s

não usa canos (5 vezes):

$ time echo XYZ | sed 's/X/A/g; s/Y/B/g; s/Z/C/g'
ABC

real    0m0.003s
user    0m0.000s
sys 0m0.004s
$ time echo XYZ | sed 's/X/A/g; s/Y/B/g; s/Z/C/g'
ABC

real    0m0.003s
user    0m0.000s
sys 0m0.000s
$ time echo XYZ | sed 's/X/A/g; s/Y/B/g; s/Z/C/g'
ABC

real    0m0.003s
user    0m0.000s
sys 0m0.000s
$ time echo XYZ | sed 's/X/A/g; s/Y/B/g; s/Z/C/g'
ABC

real    0m0.003s
user    0m0.004s
sys 0m0.000s
$ time echo XYZ | sed 's/X/A/g; s/Y/B/g; s/Z/C/g'
ABC

real    0m0.003s
user    0m0.000s
sys 0m0.000s
$ 

É claro que NÃO usar pipes é mais rápido. Por isso, pode ser usado para otimizar um script:

$ echo ABC | sed 's/A/X/g; s/X/Y/g'
YBC
$ 

A minha pergunta: A fusão do sed sempre produz o mesmo resultado?

    
por evachristine 27.04.2014 / 13:03

3 respostas

2

Sim, os dois comandos que você postou são 100% equivalentes, portanto, você pode alterar seu script com segurança para não usar pipes.

Mas seu raciocínio é falho: você só mediu o tempo que leva para echo XYZ , não as invocações sed reais. No entanto, você verá que ainda é mais rápido não usar pipes:)

dennis@spirit:~$ time sh -c 'echo XYZ | sed -e s/X/A/ | sed -e s/Y/B/ | sed -e s/Z/C/'
ABC

real    0m0.009s
user    0m0.000s
sys 0m0.012s
dennis@spirit:~$ time sh -c 'echo XYZ | sed -e s/X/A/ -e s/Y/B/ -e s/Z/C/'
ABC

real    0m0.006s
user    0m0.000s
sys 0m0.006s
    
por 27.04.2014 / 13:11
3

A resposta curta é que quando você está usando pipes para executar substituições diferentes, então o shell precisa ser dividido várias vezes.

Por outro lado, uma expressão sed contendo comandos para várias substituições requer que o shell bifurque apenas uma vez.

Assim, seria mais eficiente ter vários comandos em uma única expressão como:

sed 's/X/A/g; s/Y/B/g; s/Z/C/g'

Para responder à segunda parte, o acima é equivalente à seguinte variante mais lenta :

sed 's/X/A/g' | sed 's/Y/B/g' | sed 's/Z/C/g'
    
por 27.04.2014 / 13:11
0

Existe também uma extensão GNU para sed que condicionalmente bifurca para você:

sed '/num/s//echo "$((num+1))"/e'

info sed

e

This command allows one to pipe input from a shell command into pattern space. If a substitution was made, the command that is found in pattern space is executed and pattern space is replaced with its output. A trailing newline is suppressed; results are undefined if the command to be executed contains a NUL character.

     

Esta é uma extensão do GNU 'sed'.

    
por 27.04.2014 / 15:43

Tags