2010-12-29 10 views
19

Ho lasciato un mio programma di elaborazione dei record per alcuni minuti in esecuzione.Come evitare le chiamate eccessive di stat (/ etc/localtime) in strftime() su linux?

Questo ha mostrato in quei minuti oltre 200 000 000 chiamate a stat("/etc/localtime",..) che suona un po 'eccessivo e non necessario.

L'output strace assomiglia a questo:

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 

In sostanza si è rivelato essere uno stat() chiamata per ogni record elaborato e il colpevole si è rivelata questa linea abbastanza ordinario di codice

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

Quindi - come posso evitare strftime() chiamando stat (/ etc/localtime) ad ogni chiamata?

+4

Avete qualche prova che questo stia effettivamente causando un problema misurabile (cioè un costo di runtime significativo misurato da un profiler)? Non dovresti cercare di ottimizzare in base a * sentimenti * (come "sembra un po 'eccessivo"). Ottieni misurazioni e usa i fatti. –

+2

+1 per domande su come arrivare alla fine di glibc bloat. :-) –

+0

L'aggiunta di 'export TZ =:/etc/localtime' al mio script di shell ha eliminato le ripetute syscalls per me. – shuckc

risposta

20

Potrebbe succedere perché il fuso orario non è impostato. strftime domande /etc/localtime per trovarlo.

Provare a impostare la variabile di ambiente TZ.

Ecco il numero a link for that behavior.

+1

impostazione TZ = ":/etc/localtime" fa "aggiustare" questo. Comunque quella pagina dice anche "Non dovresti normalmente impostare TZ" – nos

+1

@nos * Nella libreria GNU C, il fuso orario predefinito è come la specifica 'TZ =:/etc/localtime' [...] *. C'è la fonte delle ripetute chiamate di 'stat'. –

+0

Non sono sicuro che questo spieghi le chiamate stat(), se imposto esplicitamente TZ =:/etc/localtime, le chiamate stat() scompaiono. – nos

Problemi correlati