Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Lire de petits morceaux d'un gros fichier

6 réponses
Avatar
Lucas Levrel
Bonjour,

Soit un fichier de N*1000 blocs de données non formatées dont je dois
extraire un bloc sur mille. Quelle stratégie serait la plus efficace,
à votre avis, sachant que N vaut plusieurs milliers ?
- Faire une boucle de
stream.read((char*)ptr, sizeof(bloc));
stream.seekg(999*sizeof(bloc),ios::cur);
- Faire stream.read((char*)data, N*1000*sizeof(bloc)); puis une boucle de
*ptr=data[i*1000];
(Pour éviter de swapper il faudrait sans doute lire des sous-blocs du
fichier mais ça ne change pas le principe.)
- Autre ?

Merci pour votre aide éclairée.
--
LL

6 réponses

Avatar
Fabien LE LEZ
On Tue, 2 Mar 2010 10:14:57 +0100, Lucas Levrel
:

Note : je suppose que tu lis à partir d'un périphérique du style
disque dur ou CD-ROM, c'est-à-dire, lent et à accès aléatoire. Dans le
cas contraire la réponse pourrait être différente.

- Faire une boucle de
stream.read((char*)ptr, sizeof(bloc));
stream.seekg(999*sizeof(bloc),ios::cur);



A priori, avec celle-là, tu lis près de mille fois moins de données
qu'avec l'autre solution. Ça devrait donc être considérablement plus
rapide.
En fait, je ne comprends même pas pourquoi tu proposes la deuxième
solution.

Mais bon, je t'invite à coder les deux solutions et comparer.

Une solution alternative, mais moyennement portable : mmap.
Par "moyennement portable", j'entends : mmap() est une fonction POSIX,
qui a un équivalent sous Windows, mais avec une autre interface. Donc,
c'est une solution utilisable sur à peu près n'importe quelle machine
pourvue d'un disque dur.
Avatar
Lucas Levrel
Le 2 mars 2010, Fabien LE LEZ a écrit :

Note : je suppose que tu lis à partir d'un périphérique du style
disque dur ou CD-ROM, c'est-à-dire, lent et à accès aléatoire. Dans le
cas contraire la réponse pourrait être différente.

- Faire une boucle de
stream.read((char*)ptr, sizeof(bloc));
stream.seekg(999*sizeof(bloc),ios::cur);



A priori, avec celle-là, tu lis près de mille fois moins de données
qu'avec l'autre solution. Ça devrait donc être considérablement plus
rapide.
En fait, je ne comprends même pas pourquoi tu proposes la deuxième
solution.



Ben je ne connais pas du tout la vitesse relative de seek par rapport
à read. Ta première remarque laisse penser que sur certains périphériques
read est beaucoup plus rapide ?

Merci d'avoir répondu.
--
LL
Avatar
Fabien LE LEZ
On Wed, 3 Mar 2010 10:33:18 +0100, Lucas Levrel
:

Ta première remarque laisse penser que sur certains périphériques
read est beaucoup plus rapide ?



Non. Si je ne m'abuse, dans ton cas précis, la solution avec seek()
est toujours au moins aussi rapide.
Toutefois, il faut que ton istream soit capable d'effectuer un seek().
Avatar
Lucas Levrel
Le 3 mars 2010, Fabien LE LEZ a écrit :

Non. Si je ne m'abuse, dans ton cas précis, la solution avec seek()
est toujours au moins aussi rapide.



OK.

Toutefois, il faut que ton istream soit capable d'effectuer un seek().



Effectivement, ça aide !

--
LL
Avatar
James Kanze
On 3 Mar, 09:33, Lucas Levrel wrote:
Le 2 mars 2010, Fabien LE LEZ a écrit :

> Note : je suppose que tu lis à partir d'un périphérique du style
> disque dur ou CD-ROM, c'est-à-dire, lent et à accès aléatoire. Dans le
> cas contraire la réponse pourrait être différente.

>> - Faire une boucle de
>> stream.read((char*)ptr, sizeof(bloc));
>> stream.seekg(999*sizeof(bloc),ios::cur);

> A priori, avec celle-là, tu lis près de mille fois moins de
> données qu'avec l'autre solution. Ça devrait donc être
> considérablement plus rapide. En fait, je ne comprends même
> pas pourquoi tu proposes la deuxième solution.

Ben je ne connais pas du tout la vitesse relative de seek par
rapport à read. Ta première remarque laisse penser que sur
certains périphériques read est beaucoup plus rapide ?



La norme, évidemment, n'en dit rien, mais dans la pratique, seek
aurait un temps plus ou moin constant, tandis que read
dépendrait du nombre d'octets lus. Pour se déplacer de petites
distances, c'est possible (mais pas nécessairement probable) que
read soit plus rapide ; pour de grandes distances, seek serait
toujours nettement plus rapide.

--
James Kanze
Avatar
Lucas Levrel
Le 3 mars 2010, James Kanze a écrit :

La norme, évidemment, n'en dit rien, mais dans la pratique, seek
aurait un temps plus ou moin constant, tandis que read
dépendrait du nombre d'octets lus. Pour se déplacer de petites
distances, c'est possible (mais pas nécessairement probable) que
read soit plus rapide ; pour de grandes distances, seek serait
toujours nettement plus rapide.



Merci.


--
LL