Pregunta

La E / S del archivo C ++ es más resistente que la E / S del archivo C. Entonces, en C ++, ¿es útil o no crear una nueva biblioteca para E / S de archivos? Me refiero a <fstream> ¿Alguien puede decir si hay algún beneficio en la E / S de archivos C ++?

¿Fue útil?

Solución

Opción

No conozco ningún proyecto real que use flujos de C ++. Son demasiado lentos y difíciles de usar. Hay varias bibliotecas más nuevas, como FastFormat y Versión Boost que dicen ser mejores, había una pieza en la última revista ACCU Overload sobre ellos. Personalmente, he usado la biblioteca c ARCHIVO durante los últimos 15 años más o menos en C ++ y todavía no veo ninguna razón para cambiar.

Velocidad

Aquí hay un pequeño programa de prueba (toco rápidamente) para mostrar el problema básico de velocidad:

#include <stdio.h>
#include <time.h>

#include<iostream>
#include<fstream>

using namespace std;

int main( int argc, const char* argv[] )
    {
    const int max = 1000000;
    const char* teststr = "example";

    int start = time(0);
    FILE* file = fopen( "example1", "w" );
    for( int i = 0; i < max; i++ )
        {
        fprintf( file, "%s:%d\n", teststr, i );
        }
    fclose( file );
    int end = time(0);

    printf( "C FILE: %ds\n", end-start );

    start = time(0);
    ofstream outdata;
    outdata.open("example2.dat");
    for( int i = 0; i < max; i++ )
        {
        outdata << teststr << ":" << i << endl;
        }
    outdata.close();
    end = time(0);

    printf( "C++ Streams: %ds\n", end-start );

    return 0;
    }

Y los resultados en mi PC:

C FILE: 5s
C++ Streams: 260s

Process returned 0 (0x0)   execution time : 265.282 s
Press any key to continue.

Como podemos ver, este simple ejemplo es 52 veces más lento. ¡Espero que haya formas de hacerlo más rápido!

NOTA: cambiar endl a '\ n' en mi ejemplo mejoró las transmisiones de C ++ por lo que es solo 3 veces más lento que las transmisiones FILE * (gracias jalf ) puede haber formas de hacerlo más rápido.

Dificultad para usar

No puedo argumentar que printf () no es conciso, pero es más flexible (IMO) y más fácil de entender, una vez que pasa el WTF inicial para los códigos de macro.

double pi = 3.14285714;

cout << "pi = " << setprecision(5)  << pi << '\n';
printf( "%.5f\n", pi );

cout << "pi = " << fixed << showpos << setprecision(3) << pi << '\n'; 
printf( "%+.3f\n", pi );

cout << "pi = " << scientific << noshowpos << pi<< '\n';
printf( "%e\n", pi );

La pregunta

Sí, es posible que exista una mejor biblioteca C ++, muchas de ellas FastFormat es esa biblioteca, solo el tiempo lo dirá.

dave

Otros consejos

Desterrar los desbordamientos del búfer me parece una gran victoria para C ++.

Por favor, eche un vistazo a

http://www.ddj.com/cpp/184403651

entonces preferirá C ++ I / O que C I / O.

En resumen, se prefiere

C si conoce el tamaño de los datos antes de leer o escribir y para la velocidad. Se prefiere C ++ si no conoce el tamaño de los datos y para un código eficiente.

En respuesta a la respuesta de David Allan Finch, arreglé un error en su código de evaluación comparativa (borró la transmisión en la versión de C ++ después de cada línea) y volví a probar:

El ciclo de C ++ ahora se ve así:

start = time(0);
{
    ofstream outdata("example2.txt");
    for( int i = 0; i < max; i++ )
    {
        outdata << teststr << ":" << i << "\n"; // note, \n instead of endl
    }
}
end = time(0);

Ejecuto 10000000 iteraciones (10 veces más que en el código original, porque de lo contrario, los números son demasiado pequeños para la pésima resolución del tiempo () para darnos algo significativo)) Y el resultado es:

G++ 4.1.2:
C FILE: 4s
C++ Streams: 6s

MSVC9.0:
C FILE: 10s
C++ Streams: 23s

(nota, la versión MSVC se ejecutó en mi computadora portátil con un disco duro significativamente más lento)

Pero esto nos da una diferencia de rendimiento de 1.5-2.3x, dependiendo de la implementación. y otros factores externos.

Las diferencias de rendimiento entre printf () / fwrite style I / O y el formato de flujos de C ++ IO dependen en gran medida de la implementación. Algunas implementaciones (visual C ++, por ejemplo) construyen sus flujos de E / S sobre objetos FILE * y esto tiende a aumentar la complejidad del tiempo de ejecución de su implementación. Tenga en cuenta, sin embargo, que no hubo una restricción particular para implementar la biblioteca de esta manera.

En mi opinión, los beneficios de C ++ I / O son los siguientes:

  • Escriba seguridad como ya se indicó anteriormente.
  • Flexibilidad de implementación. El código puede escribirse para formatear o ingresar datos específicos hacia o desde un objeto genérico ostream o istream. La aplicación puede invocar este código con cualquier tipo de objeto de flujo derivado. Si el código que he escrito y probado en un archivo ahora debe aplicarse a un socket, un puerto serie o algún otro tipo de flujo interno, puede crear una implementación de flujo específica para ese tipo de E / S. Extender la E / S de estilo C de esta manera ni siquiera es posible.
  • Flexibilidad en la configuración regional: el enfoque C de usar una única configuración regional global es, en mi opinión, muy defectuoso. He experimentado casos en los que invoqué el código de la biblioteca (una DLL) que cambió la configuración regional global debajo de mi código y desordenó por completo mi salida. Una secuencia de C ++ le permite imbuir () cualquier configuración regional a un objeto de secuencia.

std :: ifstream y std :: ofstream ya están en la biblioteca stl. No tienes que crear el tuyo.

El principal beneficio es que todas las salidas y entradas son de tipo seguro.

C y C ++ son dos lenguajes diferentes. C ++ tarda un tiempo en acostumbrarse al archivo io, pero una vez que utiliza algoritmos, excepciones, etc., tienden a encajar de forma muy natural.

Siempre que necesito tomar entradas / dar salidas en un archivo en C ++, solo uso dos líneas.

freopen("input.txt","r",stdin); // for input from file
freopen("output.txt","w",stdout);// for output from file

Ahora puede escanear variables como lo haría normalmente desde la consola, y lo que imprima como salida se mostrará en el archivo output.txt.

Por lo tanto, no creo que la E / S de archivo en c ++ sea difícil, es bastante más fácil que c.

Muchos. Inconvenientes también. Consulte las preguntas frecuentes sobre el lenguaje C ++ para más detalles. En resumen: tipos de seguridad y tipos definidos por el usuario.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top