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

Problème vitesse de lecture fichier C VB

4 réponses
Avatar
Olivier Besson
Bonjour,

Est-ce que quelqu'un sait pourquoi lorsque je fait en V.B. le code suivant :
<
Dim b as Byte
Open "MonFichier" For Binary Access Read As #1
Do While Not EOF(1)
Get #1, , b
Loop
Close #1
>
Je met 2mn 30s à lire un fichier de 100 Mo alors qu'en C avec
unsigned int c;
FILE *InputFile;
InputFile=fopen("MonFichier","rb");
while ((c=getc(InputFile)) != EOF) {
/* */
}
fclose(InputFile);
Je met moins de 10 secondes sur le meme fichier et la même machine ???

Ca fait un moment que je me pose cette question et que je suis obligé de
m'embarrasser avec des buffers de lecture pour avoir des performances
correctes.

Merci d'avance.




--

Olivier Besson
Pour m'ecrire, remplacer le <xx >de mon adresse par <com>.
(Je ne lis pas mes mails frequement)
To write me, replace <xx> part of my address by <com> (i don't read my mails
very frequently).

4 réponses

Avatar
ng
Salut,

Parce que tu lis octets par octet et le C est en effet plus rapide pour ça.
Il faut donc passer par un buffer comme tu l'as si bien dis, on aurait qqch
comme cela :

Dim k as integer, sBuffer as String
k=freefile
open "MonFichier" for binary as #k
sBuffer=Space$(LOF(k))
Get #k,,sBuffer
close #

Sinon pourquoi ne pas faire une DLL C ?

--
Nicolas G.
FAQ VB : http://faq.vb.free.fr
API Guide : http://www.allapi.net
Google Groups : http://groups.google.fr/
MZ-Tools : http://www.mztools.com/

Olivier Besson a écrit :

Bonjour,

Est-ce que quelqu'un sait pourquoi lorsque je fait en V.B. le code
suivant : <
Dim b as Byte
Open "MonFichier" For Binary Access Read As #1
Do While Not EOF(1)
Get #1, , b
Loop
Close #1



Je met 2mn 30s à lire un fichier de 100 Mo alors qu'en C avec
unsigned int c;
FILE *InputFile;
InputFile=fopen("MonFichier","rb");
while ((c=getc(InputFile)) != EOF) {
/* */
}
fclose(InputFile);
Je met moins de 10 secondes sur le meme fichier et la même machine
???

Ca fait un moment que je me pose cette question et que je suis obligé
de m'embarrasser avec des buffers de lecture pour avoir des
performances correctes.

Merci d'avance.


Avatar
François Picalausa
Bonjour/soir,

On peut aussi remarquer que la lecture par file mapping est nettement plus
rapide:
http://groups.google.com/groups?selm=eZ77fSJEDHA.2920%40TK2MSFTNGP11.phx.gbl
http://groups.google.com/groups?selm=Ox3jtGhJDHA.1720%40TK2MSFTNGP11.phx.gbl

je ne sais pas ce qu'elle donne en byte/byte ni si elle est utilisable en
byte/byte (je suppose que oui, mais je n'ai pas encore fait de recherches
approfondies sur le sujet), mais ça ne peut être qu'intéressant de la
tester!

--
François Picalausa (MVP VB)
FAQ VB : http://faq.vb.free.fr
MSDN : http://msdn.microsoft.com


"ng" a écrit dans le message de
news:eczcxCX%
Salut,

Parce que tu lis octets par octet et le C est en effet plus rapide
pour ça. Il faut donc passer par un buffer comme tu l'as si bien dis,
on aurait qqch comme cela :

Dim k as integer, sBuffer as String
k=freefile
open "MonFichier" for binary as #k
sBuffer=Space$(LOF(k))
Get #k,,sBuffer
close #

Sinon pourquoi ne pas faire une DLL C ?


Bonjour,

Est-ce que quelqu'un sait pourquoi lorsque je fait en V.B. le code
suivant : <
Dim b as Byte
Open "MonFichier" For Binary Access Read As #1
Do While Not EOF(1)
Get #1, , b
Loop
Close #1



Je met 2mn 30s à lire un fichier de 100 Mo alors qu'en C avec
unsigned int c;
FILE *InputFile;
InputFile=fopen("MonFichier","rb");
while ((c=getc(InputFile)) != EOF) {
/* */
}
fclose(InputFile);
Je met moins de 10 secondes sur le meme fichier et la même machine
???

Ca fait un moment que je me pose cette question et que je suis obligé
de m'embarrasser avec des buffers de lecture pour avoir des
performances correctes.

Merci d'avance.




Avatar
Jean-Marc
"ng" a écrit dans le message de
news:eczcxCX%
Salut,

Parce que tu lis octets par octet et le C est en effet plus rapide pour


ça.
Il faut donc passer par un buffer comme tu l'as si bien dis, on aurait


qqch
comme cela :

Dim k as integer, sBuffer as String
k=freefile
open "MonFichier" for binary as #k
sBuffer=Space$(LOF(k))
Get #k,,sBuffer
close #

Sinon pourquoi ne pas faire une DLL C ?



Hello,

j'ai créé un fichier de 50 MB (50 000 000), puis j'ai fait tourner le
programme C suivant:
int main(int argc, char **argv)
{
unsigned int c;
FILE *InputFile;
DWORD t1,t2;
unsigned long control = 0L;
char *buf;

InputFile = fopen("c://fic_50MB.txt","rb");
if(InputFile != NULL)
{
t1 = GetTickCount();
buf = malloc(50000000 +1);
while ((c = getc(InputFile)) != EOF)
{
buf[control++] = c;
}
fclose(InputFile);
t2 = GetTickCount();
printf("control : %lun", control);
printf("Elapsed (ms) : %lun", (t2-t1));
}
return EXIT_SUCCESS;
}

Compilé avec les bonnes options d'optimisation:
control : 50000000
Elapsed (ms) : 620
Press any key to continue

Le même en VB:
Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long

Private Sub Command1_Click()
Dim k As Integer, sBuffer As String
Dim t1 As Long
Dim t2 As Long
k = FreeFile
Open "c:fic_50MB.txt" For Binary As #k
t1 = GetTickCount()
sBuffer = Space$(LOF(k))
Get #k, , sBuffer
t2 = GetTickCount()
MsgBox "elapsed (ms) " & (t2 - t1), vbInformation, "result"
Close #k
End Sub

Elapsed : 871

671 ms pour le C , 871 ms pour VB ;; Bof, pas la peine de se casser la
tête.

Sinon, effectivement, une Dll en C, mais à quoi bon pour une si petite
différence (et de si petites valeurs absolues).

Jean-Marc
Avatar
Olivier Besson
Bonjour,

Merci à tous pour vos réponses.

Pour n.g. et Jean Marc :
Je ne voulais pas faire une DLL C car je veux justement convertir un
programme C en "pure" V.B.
Effectivement lorsque l'on gère des buffers depuis V.B. on arrive à
quasiment la même vitesse qu'en C (en tout cas à quelque chose de trés
acceptable), mais je voulais justement savoir si il n'y avait pas moyen
d'éviter cette gestion qui implique :
Soit de l'encapsuler dans une classe
Soit d'alourdir considérablement la boucle de lecture et d'analyse du
fichier.
De plus les get et autres sur LOF(Fichier) ne me conviennent pas du tout
pour ce que je fait (fichier de plus de 1Go avec 128 Mo de RAM = gros
problèmes).

En fait je pense qu'en C le système utilise par défaut des buffers sur les
fichiers alors que VB ne le fait pas du tout, ce qui explique la différence
énorme en lecture octet/octet.
Je vais essayer le memory mapping de François, je ne m'était jamais penché
dessus.

Merci à tous.


--

Olivier Besson
Pour m'ecrire, remplacer le <xx >de mon adresse par <com>.
(Je ne lis pas mes mails frequement)
To write me, replace <xx> part of my address by <com> (i don't read my mails
very frequently).



"Jean-Marc" a écrit dans le message de
news:40390dde$0$7030$
"ng" a écrit dans le message de
news:eczcxCX%
> Salut,
>
> Parce que tu lis octets par octet et le C est en effet plus rapide pour
ça.
> Il faut donc passer par un buffer comme tu l'as si bien dis, on aurait
qqch
> comme cela :
>
> Dim k as integer, sBuffer as String
> k=freefile
> open "MonFichier" for binary as #k
> sBuffer=Space$(LOF(k))
> Get #k,,sBuffer
> close #
>
> Sinon pourquoi ne pas faire une DLL C ?

Hello,

j'ai créé un fichier de 50 MB (50 000 000), puis j'ai fait tourner le
programme C suivant:
int main(int argc, char **argv)
{
unsigned int c;
FILE *InputFile;
DWORD t1,t2;
unsigned long control = 0L;
char *buf;

InputFile = fopen("c://fic_50MB.txt","rb");
if(InputFile != NULL)
{
t1 = GetTickCount();
buf = malloc(50000000 +1);
while ((c = getc(InputFile)) != EOF)
{
buf[control++] = c;
}
fclose(InputFile);
t2 = GetTickCount();
printf("control : %lun", control);
printf("Elapsed (ms) : %lun", (t2-t1));
}
return EXIT_SUCCESS;
}

Compilé avec les bonnes options d'optimisation:
control : 50000000
Elapsed (ms) : 620
Press any key to continue

Le même en VB:
Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long

Private Sub Command1_Click()
Dim k As Integer, sBuffer As String
Dim t1 As Long
Dim t2 As Long
k = FreeFile
Open "c:fic_50MB.txt" For Binary As #k
t1 = GetTickCount()
sBuffer = Space$(LOF(k))
Get #k, , sBuffer
t2 = GetTickCount()
MsgBox "elapsed (ms) " & (t2 - t1), vbInformation, "result"
Close #k
End Sub

Elapsed : 871

671 ms pour le C , 871 ms pour VB ;; Bof, pas la peine de se casser la
tête.

Sinon, effectivement, une Dll en C, mais à quoi bon pour une si petite
différence (et de si petites valeurs absolues).

Jean-Marc