2010-07-01 19 views
0

Quelle est la charge relative d'appel times() par rapport aux opérations de fichier telles que la lecture d'une ligne fread().Dépassement de l'appel système times() par rapport aux opérations sur les fichiers

Je sais que cela diffère probablement d'OS à OS et dépend de la durée de la ligne est, où se trouve le fichier, si c'est vraiment un tuyau qui est bloqué (ce n'est pas), etc.

Très probablement le fichier n'est pas local mais se trouve sur un lecteur NFS monté quelque part sur le réseau local. Le cas courant est une ligne de 20 caractères. Si cela aide, supposons le noyau Linux 2.6.9. Le code pas sera exécuté sur Windows.

Je suis juste à la recherche d'un guide approximatif. Est-ce sur le même ordre de grandeur? Plus rapide? Ralentissez?

But ultime: Je cherche à implémenter une routine de rappel de progression, mais je ne veux pas appeler trop souvent (car le rappel est probablement très coûteux). La majorité du travail consiste à lire un fichier texte (ligne par ligne) et à faire quelque chose avec la ligne. Malheureusement, certaines des lignes sont très long, donc simplement appeler toutes les lignes N n'est pas efficace dans les cas pathologiques trop souvent vu. J'évite d'écrire un benchmark parce que j'ai peur de l'écrire mal et j'espère que la sagesse de la foule est plus grande que mes tests à moitié cuits.

+0

Pouvez-vous simplement utiliser 'strace' comme point de repère d'un pauvre sur vos données réelles? –

Répondre

2

Sur Linux, vous pouvez écrire un petit programme qui fait beaucoup d'appels à des temps() et fread() et mesurer les temps syscall avec strace -c

par exemple

for (i = 0; i < RUNS; i++) { 
     times(&t_buf); 
     fread(buf,1,BUF,fh); 
} 

C'est quand BUF 4096 (fread sera fait appel read() à chaque fois)

# strace -c ./time_times 
% time  seconds usecs/call  calls errors syscall 
------ ----------- ----------- --------- --------- ---------------- 
59.77 0.001988   0 100000   read 
40.23 0.001338   0  99999   times 

ce qui est quand BUF 16

% time  seconds usecs/call  calls errors syscall 
------ ----------- ----------- --------- --------- ---------------- 
99.00 0.001387   0  99999   times 
    1.00 0.000014   0  392   read 
3

fread() est une fonction de bibliothèque C, pas un appel système. Par défaut, les amis sont tous des E/S tamponnées (voir setbuf), ce qui signifie que la bibliothèque alloue un tampon qui réduit la fréquence avec laquelle les appels système read() et write() doivent être effectués. Cela signifie que si vous lisez séquentiellement à partir du fichier, la bibliothèque n'émettra qu'un appel système, par exemple 100 lectures (en fonction de la taille du tampon et de la quantité de données lues à la fois).

Lorsque les appels système read() et write() sont faits, mais ils seront certainement plus lent que d'appeler times(), simplement en raison du volume de données qui doivent être échangées entre votre programme et le noyau. Si les données sont mises en cache dans les tampons du système d'exploitation (par exemple, il a été écrit par un autre processus sur la même machine il y a quelques instants), il sera encore assez rapide. Si les données ne sont pas mises en cache, alors vous devrez attendre les E/S (que ce soit sur le disque ou sur le réseau), ce qui est très lent en comparaison.

Si les données sont fraîches sur NFS, alors je serais plutôt confiant qu'appeler times() sera plus rapide que fread() en moyenne.

1

times() lit simplement les données spécifiques au processus gérées par le noyau. Les données sont gérées par le noyau pour fournir des informations pour l'appel système wait() lorsque le processus se termine. Ainsi, les données sont toujours conservées, que times() soit ou non appelée. Fread(), fwrite(), etc appelez les appels système sous-jacents - read() & write(), qui invoquent les pilotes. Les pilotes placent ensuite les données dans un tampon de noyau. C'est beaucoup plus coûteux en termes de ressources que d'invoquer times().

Est-ce ce que vous demandez?