Diferencia de rendimiento entre stdin y argumento de línea de comando

11

Para algunos comandos, es posible especificar cierta entrada como stdin o un argumento de línea de comando.

Específicamente, suponga que commandpuede tomar la entrada estándar y un nombre de archivo como argumento de línea de comando command < myfile, cat myfile | command y command myfilepuede producir el mismo resultado.

Por ejemplo,

Cuando el comando es sed:

sed s/day/night/ <myfile >new   
sed s/day/night/ myfile >new    
cat myfile | sed s/day/night/ >new

Cuando el comando es cat:

cat < myfile
cat myfile
  1. Me preguntaba si hay algunas reglas generales sobre sus actuaciones, es decir, ¿cuál de ellas suele ser la más eficiente y la que menos?
  2. ¿La redirección siempre es mejor que la tubería?
Tim
fuente
1
Deseo que todos los que hagan estas preguntas (duplicadas) vayan y escriban su propio shell desde cero como ejercicio.
alex
1
por favor no uses "¡Gracias!" en tus preguntas Vota respuestas para expresar tu agradecimiento.
alex
@ Alex: Si esto es un engaño, enlace al duplicado y trabajaremos para cerrarlo. Por lo general, se abstendría de responder una pregunta que sabe que es un duplicado y la marcará para la atención del moderador.
Caleb
1
@alex: ¿Dónde puedo aprender a escribir mi propio shell?
Tim
@Caleb: Estoy seguro de que esto se preguntó 2 o 3 veces en el último mes, simplemente no tengo el enlace a la mano :-p
alex

Respuestas:

6

La cat file | commandsintaxis se considera un uso inútil deCat . De todas sus opciones, se necesita un golpe de rendimiento porque tiene que generar otro proceso en el núcleo. Por insignificante que esto pueda resultar en el panorama general, está sobrecargado que las otras formas no tienen. Esto se ha cubierto en preguntas como: ¿Debería preocuparme por los gatos innecesarios?

Entre las otras dos formas, prácticamente no hay diferencias de rendimiento. STDIN es un nodo de archivo especial que el proceso tiene que abrir y leer como cualquier otro. Pasar un nombre de archivo en lugar de STDIN solo hace que abra un archivo diferente.

La diferencia estaría en qué características / flexibilidad está buscando.

  • Pasar el nombre del archivo al programa significaría que el archivo de entrada era buscable. Esto puede o no ser importante para el programa, pero algunas operaciones pueden acelerarse si la secuencia es buscable.
  • Conocer el archivo de entrada real le permite a su programa escribir en él. Por ejemplo, sed -ipara la edición in situ. (Nota: dado que esto tiene que crear un nuevo archivo detrás de escena, no es una ganancia de rendimiento sobre otros redireccionamientos, pero es un paso conveniente).
  • El uso de redireccionamientos de shell le brinda la capacidad de concatenar múltiples archivos o incluso utilizar la redirección de procesos. sed [exp] < file1 file2o incluso sed [exp] < <(grep command). Los detalles de este caso de uso se pueden encontrar en esta pregunta: sustitución del proceso y tubería
Caleb
fuente
La sustitución del proceso debería funcionar sin requerir que canalice el resultado; sed [exp] < <(grep command)funcionará bien como sed [exp] <(grep command)(ya que <(grep command)crea un archivo temporal con nombre para la longitud del comando que sedes perfectamente capaz de abrirse por sí solo sin asistencia de shell).
ShadowRanger
2
  1. Dado que command filesolo abre el archivo y desde entonces funciona como si lo fuera stdin, hay poca diferencia. Con la redirección de shell, simplemente abre el archivo de antemano (shell lo hace) en lugar del comando binario en sí.

  2. Si estamos hablando de cat file | commandvs. command <file, entonces este último es el preferido. No notará una diferencia de rendimiento significativa entre los dos, pero el primero es innecesariamente complicado (proceso adicional y búfer de memoria compartida para la tubería, con rendimiento limitado). Además, no puede seek(cambiar la posición del puntero del archivo arbitrariamente) en un tubería, mientras que puede en un archivo ordinario. Algunos comandos pueden usar un algoritmo más eficiente cuando seekes posible hacer ting en el archivo de entrada.

alex
fuente
Diría que se prefiere el archivo de comando sobre el comando <archivo, porque el comando podría hacer algún tipo de acceso no secuencial.
user606723
¿Y con qué lo impediría hacerlo <file? Su punto es válida para usar el nombre del archivo de entrada de nombre de archivo de salida derivan duro, por ejemplo: gzip fileproduce file.gz.
alex
tal vez no entiendo cómo funciona la redirección internamente. Digamos que redirigimos una película de 12GB a mplayer / vlc, y luego saltamos al final. ¿Qué pasaría exactamente en este caso?
user606723
1
Shell abre el archivo y bifurca un subproceso, que hereda el descriptor de archivo. El proceso de horquilla closes stdiny llamadas dupen el descriptor de archivo abierto, por lo que reemplazar el antiguo stdin(que era una especie de TTY en la mayoría de los casos.) Desde el punto de vista reproductor de películas que no hay diferencia entre eso y abrir el archivo por su nombre en el jugador en sí. El descriptor de archivo se puede buscar en ambos escenarios, por lo que cuando saltamos al final no hay diferencia detectable por el usuario.
alex