Page 1 sur 1

PB4 contre PB3 Lecture Ecriture Fichier Ascil

Publié : mar. 08/août/2006 16:48
par Coolman
j'ai lu sur le forum anglais le post d'un utilisateur qui se plaignait de la lenteur de purebasic (meme la version 4) pour ce qui est de la lecture ecriture de fichier ascil, lors de mon premier post sur ce forum j'avais effectivement noté cette lenteur en comparant avec par exemple les programmes generés par bcx (un convertisseur basic C tres efficace), j'avais cependant laissé tomber le test suite a la reaction agressive de certains... passons, j'en viens a l'object de ce post, en fait mes critiques allait vers la version 3.x, la version 4 m'a paru beaucoups plus efficace et beaucoup plus rapide a ce niveau, je voulais en avoir le coeur net car je penses que la critique n'est plus justifié, voici un code assez simple qui le prouve :

Si voulez faire le test, suivez cette ordre :

1/ Creation d'un fichier test nommé Origine.txt de 500000 lignes, Voici le code :

*** Pour purebasic 4 :

Code : Tout sélectionner

Fichcible$="Origine.txt" : Temp$=""
Maxtab.l=500000 : Boucle.l=0 
Res= CreateFile(#PB_Any, Fichcible$)
If Res
  DebutTemps.l=ElapsedMilliseconds()
  For Boucle=1 To Maxtab
          Temp$=LSet("", 80, Chr(Random(30)+66))          
          WriteStringN(Res,Temp$) 
  Next Boucle
  FinTemps.l=ElapsedMilliseconds()
  VarTemp.l=(FinTemps-DebutTemps)/1000
  MessageRequester("Information","Traitement Effectué En : "+Str(VarTemp)+" Secondes...",#PB_MessageRequester_Ok)  
  CloseFile(Res)
EndIf  
End
*** Pour purebasic 3 (utilisation commande Usefile et la syntaxe de WriteStringN differe) :

Code : Tout sélectionner

Fichcible$="Origine.txt" : Temp$=""
Maxtab.l=500000 : Boucle.l=0 
Res= CreateFile(#PB_Any, Fichcible$)
If Res
  DebutTemps.l=ElapsedMilliseconds()
  For Boucle=1 To Maxtab
          Temp$=LSet("", 80, Chr(Random(30)+66))          
          UseFile(Res) : WriteStringN(Temp$) 
  Next Boucle
  FinTemps.l=ElapsedMilliseconds()
  VarTemp.l=(FinTemps-DebutTemps)/1000
  MessageRequester("Information","Traitement Effectué En : "+Str(VarTemp)+" Secondes...",#PB_MessageRequester_Ok)  
  CloseFile(Res)
EndIf  
End
Premier constat, le programme generé avec purebasic 4 est beaucoup plus rapide, la generation du fichier ascil Origine.txt (pres de 40 mo) est pratiquement instantané (il est clair que purebasic 4 bufferise intensivement avant d'ecrire sur le disque)...


2/ Le code suivant lit sequentiellement le fichier Origine.txt qui contient 500000 lignes mais pas seulement, plus de details en bas...

*** Pour purebasic 4 :

Code : Tout sélectionner

RT$=Chr(#CR) : Fichcible$="Origine.txt" : Fichdest$="Resultas.txt"
Maxtab.l=500000 : Cmp.l=0 : Cmp2.l = 0 : Etat.l=0 : Boucle.l=0 : Crc.l=0
Res = ReadFile(#PB_Any, Fichcible$)
If Res 
  Res2= CreateFile(#PB_Any, Fichdest$)
  Dim Tab.l(Maxtab) : Posit.l=0 : DebutTemps.l=ElapsedMilliseconds()
  Repeat   
     ChaineLU$=ReadString(Res)
     If Len(ChaineLU$)>0
        Cmp=Cmp+1 : Crc=CRC32Fingerprint(@ChaineLU$, Len(ChaineLU$)) 
        If Cmp>Maxtab
           MessageRequester("Information","Desolé, depassement de capacité... ligne trouvée(s) superieur a "+Str(Maxtab)+" dans le fichier "+Fichcible$+" !!! - ARRET DU PROGRAMME...",#PB_MessageRequester_Ok)                 
           End
        EndIf     
        Etat=0 : For Boucle=1 To Cmp2 : If Tab(Boucle)=Crc : Etat=1 :  Break : EndIf : Next Boucle
        If Etat=0 : Cmp2=Cmp2+1 : Tab(Cmp2)=Crc : WriteStringN(Res2, ChaineLU$) : EndIf
      EndIf               
  Until Eof(Res) 
  FinTemps.l=ElapsedMilliseconds() : TempEcoule$=Str((FinTemps-DebutTemps)/1000)
  CloseFile(Res2)
Else
    MessageRequester("Information","Desolé, une erreur s'est produite lors de l'acces au fichier "+Fichcible$+" !"+RT$+RT$+"Arret du programme...",#PB_MessageRequester_Ok)
    End
EndIf
CloseFile(Res)
If Cmp>0 And Cmp2>0
  MessageRequester("Information","Nombre de ligne trouvé(s) dans le fichier "+Fichcible$+" : "+Str(Cmp)+RT$+RT$+"Resultas dans le fichier destination "+Fichdest$+" : "+Str(Cmp2)+RT$+RT$+RT$+"Traitement Effectué En : "+TempEcoule$+" Secondes...",#PB_MessageRequester_Ok)  
Else
 DeleteFile(Fichdest$)
EndIf  
End
*** Pour purebasic 3 :

Code : Tout sélectionner

RT$=Chr(#CR) : Fichcible$="Origine.txt" : Fichdest$="Resultas.txt"
Maxtab.l=500000 : Cmp.l=0 : Cmp2.l = 0 : Etat.l=0 : Boucle.l=0 : Crc.l=0
Res = ReadFile(#PB_Any, Fichcible$)
If Res 
  Res2= CreateFile(#PB_Any, Fichdest$)
  Dim Tab.l(Maxtab) : Posit.l=0 : DebutTemps.l=ElapsedMilliseconds()
  Repeat   
     UseFile(Res) : ChaineLU$=ReadString()
     If Len(ChaineLU$)>0
        Cmp=Cmp+1 : Crc=CRC32Fingerprint(@ChaineLU$, Len(ChaineLU$)) 
        If Cmp>Maxtab
           MessageRequester("Information","Desolé, depassement de capacité... ligne trouvée(s) superieur a "+Str(Maxtab)+" dans le fichier "+Fichcible$+" !!! - ARRET DU PROGRAMME...",#PB_MessageRequester_Ok)                 
           End
        EndIf     
        Etat=0 : For Boucle=1 To Cmp2 : If Tab(Boucle)=Crc : Etat=1 :  Break : EndIf : Next Boucle
        If Etat=0 : Cmp2=Cmp2+1 : Tab(Cmp2)=Crc : UseFile(Res2) : WriteStringN(ChaineLU$) : EndIf
      EndIf               
  Until Eof(Res) 
  FinTemps.l=ElapsedMilliseconds() : TempEcoule$=Str((FinTemps-DebutTemps)/1000)
  CloseFile(Res2)
Else
    MessageRequester("Information","Desolé, une erreur s'est produite lors de l'acces au fichier "+Fichcible$+" !"+RT$+RT$+"Arret du programme...",#PB_MessageRequester_Ok)
    End
EndIf
CloseFile(Res)
If Cmp>0 And Cmp2>0
  MessageRequester("Information","Nombre de ligne trouvé(s) dans le fichier "+Fichcible$+" : "+Str(Cmp)+RT$+RT$+"Resultas dans le fichier destination "+Fichdest$+" : "+Str(Cmp2)+RT$+RT$+RT$+"Traitement Effectué En : "+TempEcoule$+" Secondes...",#PB_MessageRequester_Ok)  
Else
 DeleteFile(Fichdest$)
EndIf  
End
Que fait ce code concretement, le fichier Origine.txt est parcouru sequentiellement, un autre fichier est cree pour y ecrire des donnees tout en ne tenant pas compte des doublons, j'ai utilise la commande crc pour savoir si la ligne a deja ete inscrite, le code est issu d'un besoin, je l'utilise frequement pour nettoyer un fichier de plusieurs megas en eliminant les doublons...

Si vous faite le test, et j'en suis moi meme un peu surpris, la version purebasic 4 execute le programme en pratiquement 1 a 4 secondes alors que la version pour purebasic 3 le fait en 53 secondes, j'ai pensé au depart avoir fait une erreur quelques part, mais je n'ai rien trouvé, la difference est enorme, l'auteur a fait la un travail d'optimisation apreciable...

Le test a ete effectue sur un P4 2.6

Reste a translater le code en bcx pour comparer, mais je n'ai pas vraiment le temps pour le moment, si quelqu'un veut retranscrire le code en c, je serais curieux de voir ca...