¿Cuál es el significado de incluir
ios_base::sync_with_stdio(false);
cin.tie(NULL);
en programas C ++?
En mis pruebas, acelera el tiempo de ejecución, pero ¿hay algún caso de prueba que deba preocuparme al incluir esto?
¿Las dos afirmaciones siempre tienen que estar juntas, o es la primera suficiente, es decir, ignorar cin.tie(NULL)
?
Además, ¿está permitido usar comandos simultáneos C y C ++ si su valor se ha establecido en false
?
https://www.codechef.com/viewsolution/7316085
El código anterior funcionó bien, hasta que lo usé scanf/printf
en un programa C ++ con el valor como true
. En este caso, dio una falla de segmentación. ¿Cuál podría ser la posible explicación para esto?
Respuestas:
Las dos llamadas tienen significados diferentes que no tienen nada que ver con el rendimiento; El hecho de que acelere el tiempo de ejecución es (o podría ser ) solo un efecto secundario. Debe comprender lo que hace cada uno de ellos y no incluirlos a ciegas en todos los programas porque parecen una optimización.
Esto deshabilita la sincronización entre las secuencias estándar C y C ++. Por defecto, todas las transmisiones estándar están sincronizadas, lo que en la práctica le permite mezclar E / S de estilo C y C ++ y obtener resultados sensibles y esperados. Si deshabilita la sincronización, las transmisiones de C ++ pueden tener sus propios buffers independientes, lo que hace que la mezcla de E / S al estilo C y C ++ sea una aventura.
También tenga en cuenta que las secuencias sincronizadas de C ++ son seguras para subprocesos (la salida de diferentes subprocesos puede intercalarse, pero no obtiene carreras de datos).
Esto se desata
cin
decout
. Las secuencias vinculadas aseguran que una secuencia se vacíe automáticamente antes de cada operación de E / S en la otra secuencia.Por defecto
cin
está vinculado acout
garantizar una interacción sensible del usuario. Por ejemplo:Si
cin
ycout
están vinculados, puede esperar que la salida se vacíe (es decir, sea visible en la consola) antes de que el programa solicite la entrada del usuario. Si desata las transmisiones, el programa puede bloquear la espera de que el usuario ingrese su nombre, pero el mensaje "Ingresar nombre" aún no está visible (porquecout
está almacenado de forma predeterminada, la salida se vacía / muestra en la consola solo a pedido o cuando el el búfer está lleno).Así que si desatar
cin
a partircout
, debe asegurarse para eliminarcout
manualmente cada vez que desea mostrar algo antes de esperar la entrada encin
.En conclusión, sepa qué hace cada uno de ellos, comprenda las consecuencias y luego decida si realmente quiere o necesita el posible efecto secundario de la mejora de la velocidad.
fuente
cout
está almacenado en un búfer por una razón, si lo descarga con demasiada frecuencia, cuando realmente no lo necesita, es posible que vea un impacto en el rendimiento.scanf()
, deshabilitar el almacenamiento en búfer por completo o cambiar al almacenamiento en línea (que debe enjuagarse después de la nueva línea o cuando se lee la entradastdin
; consulte linux.die.net/man/3/setlinebuf ).Esto es para sincronizar las E / S del mundo C y C ++. Si sincroniza, tiene la garantía de que las órdenes de todos los IO son exactamente lo que espera. En general, el problema es el almacenamiento en búfer de E / S que causa el problema, la sincronización permite que ambos mundos compartan los mismos almacenamientos intermedios. Por ejemplo
cout << "Hello"; printf("World"); cout << "Ciao";
; sin sincronización nunca sabrá si obtendráHelloCiaoWorld
oHelloWorldCiao
oWorldHelloCiao
...tie
le permite tener la garantía de que los canales de E / S en el mundo de C ++ están vinculados entre sí, lo que significa, por ejemplo, que cada salida se ha vaciado antes de que ocurran las entradas (piensecout << "What's your name ?"; cin >> name;
).Siempre puede mezclar E / S C o C ++, pero si desea un comportamiento razonable, debe sincronizar ambos mundos. Tenga en cuenta que en general no se recomienda mezclarlos, si programa en C use C stdio, y si programa en C ++ use streams. Pero es posible que desee mezclar bibliotecas C existentes en código C ++, y en tal caso es necesario sincronizar ambas.
fuente
cout <<
no pueden cambiar el orden, porCiaoHelloWorld
lo que no es posible para su caso de ejemplo. La sincronización se trata estrictamente de diferentes métodos de almacenamiento en búfer.El uso
ios_base::sync_with_stdio(false);
es suficiente para desacoplar las secuenciasC
yC++
. Puede encontrar una discusión sobre esto en Standard C ++ IOStreams and Locales , de Langer y Kreft. Señalan que su funcionamiento está definido por la implementación.La
cin.tie(NULL)
llamada parece estar solicitando un desacoplamiento entre las actividades encin
ycout
. No puedo explicar por qué usar esto con la otra optimización debería causar un bloqueo. Como se señaló, el enlace que proporcionó es malo, por lo que no hay especulaciones aquí.fuente
Es solo algo común para hacer que la entrada cin funcione más rápido.
Para una explicación rápida: la primera línea desactiva la sincronización del búfer entre el flujo cin y las herramientas stdio de estilo C (como scanf o gets), por lo que cin funciona más rápido, pero no puede usarlo simultáneamente con las herramientas stdio .
La segunda línea desata cin de cout : de forma predeterminada, el búfer de cout se vacía cada vez que lee algo de cin . Y eso puede ser lento cuando lees repetidamente algo pequeño y luego escribes algo pequeño muchas veces. Entonces, la línea apaga esta sincronización (al vincular literalmente cin a nulo en lugar de cout ).
fuente