2011-04-24 7 views
11

En mi SAX XML análisis de devolución de llamada (XCode 4, LLVM), estoy haciendo un montón de llamadas a este tipo de código:¿Puedo contar con mi compilador para optimizar strlen en const char *?

static const char* kFoo = "Bar"; 

void SaxCallBack(char* sax_string,.....) 
{ 
    if (strcmp(sax_string, kFoo, strlen(kFoo)) == 0) 
    { 

    } 


    } 

¿Es seguro asumir que strlen (kFoo) está optimizado por el ¿compilador?

(El código de ejemplo de Apple habían pre-calculada strlen (kFoo), pero creo que esto es propenso a errores para un gran número de cadenas constantes.)

Editar: La motivación para la optimización de: analizar mi mapa SVG en el iPod tocar 2G lleva 5 segundos (!) con NSXMLParser. Por lo tanto, quiero cambiar a lib2xml y optimizar las comparaciones de cadenas.

+0

Consejos de optimización para principiantes: no. Consejos de optimización para expertos: todavía no. A menos que los perfiles hayan demostrado que es aquí donde está el cuello de la botella en su programa, creo que no debería preocuparse por ello. – freespace

+2

Quieres decir 'strncmp', ¿verdad? Porque podrías usar 'strcmp' (con dos argumentos) y sería equivalente a la condición tal como está escrita actualmente. –

+4

@freespace La pregunta es "¿Puedo contar con mi compilador para optimizar ...?". A menos que piense que este consejo se aplica a los compiladores, no veo cómo es relevante para esta pregunta. –

Respuesta

6

Si con "LLVM" quiere decir clang, entonces sí, puede contar con clang -O para optimizar el strlen de distancia. Esto es lo que el código para su función se ve así:

_SaxCallBack: 
Leh_func_begin1: 
    pushq %rbp 
Ltmp0: 
    movq %rsp, %rbp 
Ltmp1: 
    leaq L_.str1(%rip), %rsi 
    movl $3, %edx 
    callq _strncmp 
    ... 

he cambiado el strcmp en strncmp, pero el tercer argumento de hecho ha sido sustituida por la inmediata $3.

Tenga en cuenta que gcc 4.2.1 -O3 no optimiza este strlen llamada, y que sólo se puede esperar que funcione en las condiciones precisas de su pregunta (sobre todo, la cadena y la llamada a strlen deben estar en el mismo archivo).

+1

Revisé el compilador de Microsoft. También optimizó la llamada cuando se usa la optimización '/ O2'. –

+2

gcc optimiza la llamada 'strlen()' si 'kFoo' se hace' const' (es decir, 'static const char * const kFoo =" Bar ";'). – caf

+0

'clang versión 2.8' no optimiza' strlen() 'sin el segundo' const' en mi máquina. – jfs

1

En general, no puede contar con ello. Sin embargo, puede usar 'sizeof' y aplicarlo a un literal de cadena. Por supuesto, esto significa que no puede definir 'kFoo' de la forma en que se definió originalmente.

Lo siguiente debería funcionar en todos los compiladores y en todos los niveles de optimización.

#define kFoo "..." 

    ... strcmp(... sizeof(kFoo)) 
+4

Tenga en cuenta que en este caso 'sizeof (kFoo) == strlen (kFoo) + 1' ('sizeof' incluye el término' NUL') – vladr

9

No escriba cosas como:

static const char* kFoo = "Bar"; 

Usted ha creado una variable de llamado kFoo que apunta a los datos constantes. El compilador podría detectar que esta variable no cambia y optimizarla, pero de lo contrario, habrá inflado el segmento de datos de su programa.

también no escribir cosas como:

static const char *const kFoo = "Bar"; 

Ahora la variable de kFoo es const Calificado y no modificable, pero si se utiliza en código independiente de posición (bibliotecas, etc. compartidos), el contenido se todavía varían en el tiempo de ejecución y, por lo tanto, agregará costos de inicio y memoria a su programa. En su lugar, utilice:

static const char kFoo[] = "Bar"; 

o incluso:

#define kFoo "Bar" 
+0

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Gracias R. !! – Jacko

+7

No recomendaría la opción '# define' en C++, ¡definitivamente no! Gracias por la información sobre el tema del puntero. –

+1

La pregunta está etiquetada C, no C++. Pero sí, preferiría la forma 'static const char []' de todos modos. –

0

Seguimiento pregunta:

¿Ha probado el siguiente?

static std::string const kFoo = "BAR"; 

void SaxCallBack(char* sax_string,.....) 
{ 
    if (sax_string == kFoo) 
    { 

    } 


} 

Es una ganancia neta en la legibilidad, pero no tengo idea del costo de rendimiento. Como alternativa, si tiene que despachar por su cuenta, he encontrado que usar un enfoque de máquina de estado (con pila) es mucho mejor en cuanto a facilidad de lectura, y también puede ganar en rendimiento (en lugar de tener un gran tamaño). número de etiquetas para encender, solo tiene las etiquetas que se pueden cumplir en este momento).

+0

Gracias, Matthieu. Estoy buscando un generador de máquina de estado llamado Ragel, que puede generar analizadores en varios idiomas. – Jacko

Cuestiones relacionadas