2010-12-29 10 views
19

Dejé funcionando un programa de procesamiento de registros durante unos minutos bajo esfuerzo.Cómo evitar llamadas excesivas de estadísticas (/ etc/localtime) en strftime() en Linux?

Esto mostró en esos minutos más de 200 000 000 llamadas a stat("/etc/localtime",..) que suena un poco excesivo e innecesario.

La salida de strace se parece a esto:

write(1, "C137015 393393093052629137110 47"..., 16384) = 16384 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2225, ...}) = 0 
read(0, "\224q\1\207\0\0\202\1\4\203\1\4\204\1\1\205\1\1\206\1\7\207\1\6\211\1\22\212\1\22\213\1"..., 16384) = 16384 

Esencialmente resultó ser 1 stat llamada() para cada registro procesado y el culpable resultó ser esta línea bastante ordinario del código

strftime(call->date_time,DATELEN,"%Y%m%d %H%M%S",&tm_buf); 

Entonces, ¿cómo puedo evitar strftime() llamar a stat (/ etc/localtime) en cada llamada?

+4

¿Tiene alguna prueba de que esto esté causando realmente un problema mensurable (es decir, un costo de tiempo de ejecución significativo medido por un generador de perfiles)? No debería tratar de optimizar basándose en * sentimientos * (como "suena un poco excesivo"). Obtenga mediciones y use hechos. –

+2

+1 si tiene alguna pregunta acerca de cómo llegar al final de glibc bloat. :-) –

+0

Añadiendo 'export TZ =:/etc/localtime' a mi shell script eliminó las syscalls repetidas para mí. – shuckc

Respuesta

20

Podría estar haciendo eso porque su zona horaria no está configurada. strftime consultas /etc/localtime para encontrarlo.

Intente establecer la variable de entorno TZ.

Aquí está a link for that behavior.

+1

configuración TZ = ":/etc/localtime" "arregla" esto. Sin embargo, esa página también indica "Normalmente no es necesario configurar TZ" – nos

+1

@nos * En la biblioteca C de GNU, la zona horaria predeterminada es como la especificación 'TZ =:/etc/localtime' [...] *. Ahí está la fuente de las repetidas llamadas 'stat'. –

+0

No estoy seguro de que se expliquen las llamadas stat(), si configuré TZ =:/etc/localtime explícitamente, las llamadas stat() desaparecerán. – nos

Cuestiones relacionadas