sstream example español c++ performance parsing

c++ - español - stringstream example



c++ stringstream es demasiado lento, ¿cómo acelerar? (4)

¿Has considerado usar lexical_cast de boost?

http://www.boost.org/doc/libs/1_46_1/libs/conversion/lexical_cast.htm

Edit: por cierto, el clear() debe ser redundante.

Posible duplicado:
La forma más rápida de leer valores numéricos de un archivo de texto en C ++ (doble en este caso)

#include <ctime> #include <cstdlib> #include <string> #include <sstream> #include <iostream> #include <limits> using namespace std; static const double NAN_D = numeric_limits<double>::quiet_NaN(); void die(const char *msg, const char *info) { cerr << "** error: " << msg << " /"" << info << ''/"''; exit(1); } double str2dou1(const string &str) { if (str.empty() || str[0]==''?'') return NAN_D; const char *c_str = str.c_str(); char *err; double x = strtod(c_str, &err); if (*err != 0) die("unrecognized numeric data", c_str); return x; } static istringstream string_to_type_stream; double str2dou2(const string &str) { if (str.empty() || str[0]==''?'') return NAN_D; string_to_type_stream.clear(); string_to_type_stream.str(str); double x = 0.0; if ((string_to_type_stream >> x).fail()) die("unrecognized numeric data", str.c_str()); return x; } int main() { string str("12345.6789"); clock_t tStart, tEnd; cout << "strtod: "; tStart=clock(); for (int i=0; i<1000000; ++i) double x = str2dou1(str); tEnd=clock(); cout << tEnd-tStart << endl; cout << "sstream: "; tStart=clock(); for (int i=0; i<1000000; ++i) double x = str2dou2(str); tEnd=clock(); cout << tEnd-tStart << endl; return 0; }

Strtod: 405
corriente: 1389

actualización: eliminar undersocres, env: win7 + vc10


El formato de texto a número C / C ++ es muy lento. Las transmisiones son terriblemente lentas pero incluso el análisis del número C es lento porque es bastante difícil hacerlo correctamente hasta el último bit de precisión.

En una aplicación de producción donde la velocidad de lectura era importante y donde se sabía que los datos tenían como máximo tres dígitos decimales y ninguna notación científica obtuve una gran mejora al codificar a mano una función de análisis flotante que maneja solo el signo, la parte entera y cualquier número de decimales ( por "vasto" quiero decir 10 veces más rápido en comparación con strtod ).

Si no necesitas un exponente y la precisión de esta función es suficiente, este es el código de un analizador similar al que escribí en ese entonces. En mi PC ahora es 6,8 veces más rápido que strtod y 22,6 veces más rápido que sstream.

double parseFloat(const std::string& input) { const char *p = input.c_str(); if (!*p || *p == ''?'') return NAN_D; int s = 1; while (*p == '' '') p++; if (*p == ''-'') { s = -1; p++; } double acc = 0; while (*p >= ''0'' && *p <= ''9'') acc = acc * 10 + *p++ - ''0''; if (*p == ''.'') { double k = 0.1; p++; while (*p >= ''0'' && *p <= ''9'') { acc += (*p++ - ''0'') * k; k *= 0.1; } } if (*p) die("Invalid numeric format"); return s * acc; }


En general, si necesita velocidad, considere esta biblioteca:

http://www.fastformat.org/

(No estoy seguro si contiene funciones para convertir cadenas o flujos a otros tipos, por lo que es posible que no responda a su ejemplo actual).

Para el registro, tenga en cuenta que está comparando manzanas con naranjas aquí. strtod() es una función simple que tiene un solo propósito (convertir cadenas al doble), mientras que stringstream es un mecanismo de formateo mucho más complejo, que está lejos de ser optimizado para ese propósito específico. Una comparación más justa sería comparando stringstream con la línea de funciones sprintf / sscanf, que sería más lenta que strtod() pero aún más rápida que stringstream. No estoy exactamente seguro de qué es lo que hace que el diseño de stringstream sea más lento que el de sprintf / sscanf, pero parece que ese es el caso.


secuencia de cadena es lenta. Bastante muy lento. Si está escribiendo algo crítico para el rendimiento que actúa en grandes conjuntos de datos (por ejemplo, cargar activos después de un cambio de nivel durante un juego) no utilice secuencias de cadenas. Recomiendo usar las funciones de análisis de la biblioteca de la vieja escuela para el rendimiento, aunque no puedo decir cómo se comparan con algo como el espíritu de impulso.

Sin embargo, en comparación con las funciones de la biblioteca c, las secuencias de cadenas son muy elegantes, legibles y confiables, por lo que si lo que estás haciendo no es un rendimiento ciriático, te recomiendo adherirte a las corrientes.