En general, el usuario de las clases de flujo no debería interferir con el enjuague de la secuencia si se desea el máximo rendimiento: las corrientes descargan internamente su búfer cuando está lleno. En realidad, esto es más eficiente que esperar hasta que todos los resultados estén listos, especialmente con archivos de gran tamaño: los datos almacenados en el búfer se escriben mientras todavía es probable que estén en la memoria. Si crea un gran buffer y solo lo escribe una vez que el sistema de memoria virtual haya puesto partes de los datos en el disco pero no en el archivo. Necesitaría ser leído del disco y escrito de nuevo.
El punto principal con respecto a std::endl
es que las personas abusan de un final de línea que hace que el búfer se descargue y no están conscientes de las implicaciones de rendimiento. La intención de std::endl
es que a las personas se les dé el control para descargar archivos en puntos razonables. Para que esto sea efectivo, necesitan saber lo que están haciendo. Lamentablemente, había demasiada gente ignorante de lo que hace std::endl
que anunciaba su uso como un final de línea, de modo que se usa en muchos lugares donde está completamente equivocado.
Dicho esto, a continuación se detallan una serie de cosas que quizás desee intentar para mejorar el rendimiento. Supongo que necesita una salida formateada (que el uso de std::ofstream::write()
no le proporcionará).
- Obviamente, no use
std::endl
a menos que tenga que hacerlo. Si el código de escritura ya existe y usa std::endl
en muchos lugares, algunos de los cuales posiblemente estén fuera de su control, puede usar un buffer de flujo de filtrado que usa su buffer interno de tamaño razonable y que no reenvía llamadas a su función sync()
al subyacente buffer de transmisión Aunque esto implica una copia adicional, esto es mejor que algunos fallos espúreos, ya que estos son órdenes de magnitud más caros.
- Aunque no debería tener un efecto en
std::ofstream
s, llamar al std::ios_base::sync_with_stdio(false)
se usa para afectar el rendimiento en algunas implementaciones.Te recomendamos que utilices una implementación diferente de IOstream si esto tiene un efecto porque probablemente haya más cosas incorrectas con respecto al rendimiento.
- Asegúrese de estar utilizando un
std::locale
cuyo std::codecvt<...>
devuelve true
al llamar a su always_noconv()
. Esto se puede verificar fácilmente usando std::use_facet<std::codecvt<char, char, stdd::mbstate_t> >(out.get_loc()).always_noconv()
. Puede usar std::locale("C")
para obtener un std::locale
para lo cual esto debería ser cierto.
- Algunas implementaciones de entornos locales utilizan implementaciones muy ineficientes de sus facetas numéricas e, incluso si son razonablemente buenas, la implementación predeterminada de la faceta
std::num_put<char>
aún puede hacer cosas que realmente no necesita. Especialmente si su formateo numérico es razonablemente simple, es decir, no sigue cambiando los indicadores de formato, no ha reemplazado el mapeo de caracteres (es decir, no usa una faceta std::ctype<char>
graciosa), etc., puede ser razonable usar una función personalizada std::num_put<char>
faceta: es bastante fácil crear una función de formateo rápida pero simple para tipos enteros y una función de buen formato para puntos flotantes que no utiliza snprintf()
internamente.
Algunas personas han sugerido el uso de archivos mapeados en memoria, pero esto solo funciona razonablemente cuando se conoce con antelación el tamaño del archivo de destino. Si este es el caso, esta es una buena forma de mejorar el rendimiento, de lo contrario no vale la pena molestarse. Tenga en cuenta que puede usar el formato de flujo con los archivos asignados de memoria (o, más generalmente, con cualquier tipo de interfaz de salida) creando un std::streambuf
personalizado que utiliza la interfaz de mapeo de memoria. Encuentro que el mapeo de memoria a veces es efectivo cuando se usan con std::istream
s. En muchos casos, las diferencias realmente no importan mucho.
Hace mucho tiempo escribí mi propia implementación IOStreams and locales que no sufre de algunos de los problemas de rendimiento mencionados anteriormente (está disponible en my site pero está un poco pasada de moda y no la he tocado por casi 10 años ahora). Todavía hay muchas cosas que se pueden mejorar en esta implementación, pero no tengo una implementación actualizada que estaría listo para publicar en alguna parte. Pronto, con suerte, algo que sigo pensando desde hace casi 10 años ...
¿Necesita enjuagar el archivo o no? No veo cómo puede vaciar el archivo y también obtener las ventajas de rendimiento de no descargar el archivo. (Si desea un rendimiento óptimo de escritura de archivos, la mejor opción es ir con un archivo mapeado en la memoria). – Mankarse
Si le preocupa el rendimiento, no debe utilizar los operadores '<<'. debe adherirse a los métodos de lectura y escritura con un tamaño de búfer suficiente o al mapeo de memoria de su archivo (debe hacerse de forma inteligente). Estás en lo cierto con la comprensión de '\ n' y std :: endl :) – Arunmu