2011-04-04 17 views
13

Mi objetivo es encontrar la biblioteca más rápida de C++ para convertir int en cadena, viceversa, y analizar.Alto rendimiento latencia baja C++ cadena personalizada clase

Cualquiera que haya experimentado con el rendimiento de C++ se dará cuenta rápidamente de que la clase de cadena de STL tiene un rendimiento terrible en comparación con las operaciones aritméticas de STL int.

Algunos puntos de referencia de la muestra de mi 3.3 GHz Intel, GCC, CentOS 5,5 máquina:

memcpy  0.004000 microsec/op 
atoi   0.025000 microsec/op 
atof   0.133000 microsec/op 
strtod  0.133000 microsec/op 
atof   0.135108 microsec/op 
(char) uchar 0.001801 microsec/op 
(char) ushort 0.001801 microsec/op 
cache accs 0.010505 microsec/op 
maplookup  0.128534 microsec/op 
add_int  0.002456 microsec/op 

puede ver rápidamente que las operaciones de cadena se convertirá en un cuello de botella para las aplicaciones de mensajería de alta velocidad.

He localizado otras librerías para cadenas de alto rendimiento (enumeradas), pero estoy escribiendo esperando que alguien haya tenido una dificultad similar y haya encontrado alguna solución, incluyendo posiblemente escribir su propia clase de cadena.

+3

Bueno, usted ha hecho los puntos de referencia. Pero mi pregunta es: ¿realmente importa optimizar esta clase? ¿Hubo una cantidad significativa (> 20% de tiempo) de tiempo invertido en cadenas reales <-> de conversiones numéricas? Y también, ¿por qué molestarse en enviar los datos numéricos como cadenas? Sería más eficiente simplemente enviarlos en su representación nativa (o una representación intermedia, pero aún numérica) –

+5

¿Tiene usted una aplicación que ha perfilado e identificado una cadena de procesamiento de cuello de botella, o simplemente está suponiendo que podría ser un cuello de botella en alguna aplicación hipotética? –

+6

Creo que encontrará que esto no es realmente un cuello de botella. La latencia de red oscurecerá cualquiera de estos tiempos en varios órdenes de magnitud. –

Respuesta

5

usted no proporcionó toda la información acerca de sus servidores, pero echar un vistazo a estas bibliotecas de AMD e Intel:

AMD String Library

Intel Integrated Performance Primitives

Ambos utilizan SSE extensions para acelerar las operaciones de cadenas.

Por lo que puedo ver, no tienen atoi(), pero podría usar las bibliotecas para ubicar los decimales en la entrada. Dada la ubicación y la longitud de la cadena, sería trivial escribir una conversión utilizando los intrínsecos de SSE.

0

Escribí mi propia clase de cadena (gstring). Es solo encabezado y me permite reutilizar almacenamientos intermedios de pila y ajustar cadenas de C fácilmente. La codificación de enteros está incluida. La decodificación entera es una envoltura alrededor de strtol.

me permite analizar cadenas fácilmente:

uint32_t pos = 0 
gstring gs1 = gstr.netstringAt (pos, &pos); // gs1 is a *view* into gstr 
gstring gs2 = gstr.netstringAt (pos, &pos); 
int int1 = gstr.intAt (pos, &pos); if (gstr[pos] == ',') ++pos; 
int int2 = gstr.intAt (pos, &pos); if (gstr[pos] == ',') ++pos; 

También hay Str, pero su comportamiento en una plataforma de 64 bits no es muy claro para mí.
También hay FBString. Ellos promise que las conversiones de "locura :: a" son rápidas.

0

Envíe todo en hexadecimal ASCII y escriba las rutinas de conversión en lenguaje ensamblador.

0

Es posible que desee ver en http://alexott.blogspot.fr/2010/01/boostspirit2-vs-atoi.html

Puede ser que le dará un mayor aumento de rendimiento si se está analizando algo más complicado que una cadena.

Pero como dicen algunos comentarios, ¿hay realmente un cuello de botella con manipulaciones de cadena?¿No puedes evitarlos antes?

0

Los autores de la biblioteca Boost Karma hicieron una comparación de varios enteros con los métodos de conversión de cadenas here. En this post Hice una comparación similar, pero incluyendo el format library. No necesita una clase de cadena personalizada para esto; por ejemplo, en el caso de la biblioteca de formatos, la salida se almacena en un búfer interno que puede convertir a std::string o acceder como una cadena C o como una matriz de caracteres para puede evitar la creación de cadenas si es necesario.

0
int castString(const char * str) 
{ 
    int val = 0; 
    while(*str) { 
     val = val*10 + (*str++ - '0'); 
    } 
    return val; 
} 

Esto es muy rápido

+2

¡Y sin errores! ¡Qué alma tan confiada eres! Además, esto no maneja la entrada con signo, por lo que probablemente debería devolver unsigned int. – Speed8ump

Cuestiones relacionadas