Optimisation...s #3

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Optimisation...s #3

Message par Progi1984 »

Bonjour, je viens pour gagner encore une dizaine de minutes.

Voilà, je fais actuellement ce code

Code : Tout sélectionner

ForEach LL_Lines()
	If LL_Lines()\function = LL_DLLFunctions()\FuncName
		sASMContent + LL_Lines()\line + #System_EOL
	EndIf
Next
Ce code veut dire, je parse toutes les lignes, si elle font partie de la fonction que je veux écrire, je l'ajoute dans le string avant écriture. Mais pour parser toutes les LL_Lines() -180000 items - et l'ajouter dans sASMContent, ca me prend encore 12minutes.

Donc comment pourrais je optimiser ca ?
brossden
Messages : 833
Inscription : lun. 26/janv./2004 14:37

Message par brossden »

Je pense qu'il y a très certainement moyen d'optimiser mais il faudrait avoir l'ensemble du code pour définir un algo plus performant.
Si tu mets en ligne toutes les données on pourra certainement t'aider mais avec aussi peu de données je ne vois pas comment on peut faire.
Denis

Bonne Jounée à tous
gnozal
Messages : 832
Inscription : mar. 07/déc./2004 17:35
Localisation : France
Contact :

Message par gnozal »

Ben, même réponse que pour #1 je dirais.

Si la liste LL_Lines() était triée, la recherche serait beaucoup plus rapide par technique dichotomique.
Si tu ne peux pas la trier (l'ordre des éléments est important ?), tu peux toujours utiliser une copie de la liste triée mise à jour chaque fois que tu ajoutes un élément à la liste originale.
Ou ajouter un champ 'Ordre' dans la structure de la liste LL_Lines(), \Ordre étant incrémenté à chaque ajout d'élément dans la liste. Tu tries la liste sur \function, et tu peux reconstituer l'ordre à la fin en triant sur \Ordre.
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

L'ordre des lignes dans LL_Lines() est important, car elles sont rentrés au fur et à mesure de la lecture du fichier ASM original.

En fait ce morceau extrait simplement le code correspondant à une certaine fonction pour l'écrire dans un fichier (fichier stocké dans la chaine sASMContent avant écriture).

Vous voyez ce que je veux dire ?
brossden
Messages : 833
Inscription : lun. 26/janv./2004 14:37

Message par brossden »

Je pense avoir compris ce que tu veux faire. Selon moi tu veux faire un pseudo compilateur qui reprend tes lignes de code et qui les remplace par la fonction s'y rapportant. Si ce n'est pas cela merci d'être un peu plus explicite !
Denis

Bonne Jounée à tous
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Je t'explique :

C'est pour le projet Moebius : projet francais "concurrent" de Tailbite.

Cette partie du code réécrit dans des fichiers distincts le code ASM pour chaque procédure.

Mais la lenteur ne se fait pas le parsage de la liste chainées, mais dans l'ajout à la fin du code de la ligne de la chaine qui contient ce code ASM, qui ralentit le parsage.

En fait, la liste chainée contient chq ligne du code ASM et la fonction référente. J'ai besoin d'écrire ces lignes dans un fichier spécifique par fonction.
brossden
Messages : 833
Inscription : lun. 26/janv./2004 14:37

Message par brossden »

Je pense avoir compris alors tu peux essayer le code suivant et merci de me dire si tu gagnes quelque chose :

Code : Tout sélectionner


; si on admet que ta chaine fera au maximum 1 Mo, mais il reste possible 
de l'adapter par une autre valeur
*Mem = AllocateMemory(1000000)
Pointeur.q=0

ForEach LL_Lines()
  If LL_Lines()\Function = LL_DLLFunctions()\FuncName
    PokeS(*Mem + Pointeur,LL_Lines()\line + #System_EOL)
    Pointeur + Len(LL_Lines()\line + #System_EOL)
  EndIf
Next

sASMContent = PeekS(*Mem,Pointeur")

FreeMemory(*Mem)
Dernière modification par brossden le jeu. 23/avr./2009 10:45, modifié 1 fois.
Denis

Bonne Jounée à tous
gnozal
Messages : 832
Inscription : mar. 07/déc./2004 17:35
Localisation : France
Contact :

Message par gnozal »

Progi1984 a écrit :... Mais la lenteur ne se fait pas le parsage de la liste chainées, mais dans l'ajout à la fin du code de la ligne de la chaine qui contient ce code ASM, qui ralentit le parsage...
Si c'est l'ajout des chaînes qui est critique, tu pourrais utiliser un 'string builder', théoriquement plus rapide qu'une concaténation de chaînes : http://www.purebasic.fr/english/viewtopic.php?t=13015 (non testé).
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Juste un tit test assez concluant :

Code : Tout sélectionner

Structure StringBuilder
  pString.l
  StringSize.l
  MemSize.l
  BlockSize.l
  InitDone.l
  ; Initialized to 0 (FALSE) at creation.  Means by default
  ; we have not initialized the structure/class.
EndStructure

Procedure.l sbCreate(BlockSize.l)
   ;
   Protected *sbClass.StringBuilder
   ;
   *sbClass = AllocateMemory(SizeOf(StringBuilder))
   ;
   If *sbClass\InitDone : FreeMemory(*sbClass\pString) : EndIf
   ; If the stringbuilder is already initialized, free the memory of the string.
   ; BlockSize min. 1024 ($400) Byte
   If BlockSize < $400 : BlockSize = $400 : EndIf
   ; BlockSize max. 1 MByte ($100000) Byte
   If BlockSize > $100000 : BlockSize = $100000 : EndIf
   ;
   If BlockSize <> (BlockSize & $FC00)
      BlockSize = (BlockSize & $FC00) + 1024
   EndIf
   ;
   *sbClass\BlockSize = BlockSize
   *sbClass\StringSize = 0
   *sbClass\pString = AllocateMemory(BlockSize)
   ; Allocate the memory needed for our string
   If *sbClass\pString <> 0
      ; Allocation went fine, let the structure know we initialized everything fine.
      *sbClass\InitDone = #True
      *sbClass\MemSize = *sbClass\BlockSize
      ; Set our memory size used to the size of the block.
   Else
      ; Problem with allocation - let it know we did not initialize
      *sbClass\InitDone = #False
      *sbClass\MemSize = 0
   EndIf
   ;
   ProcedureReturn *sbClass
   ; Return the pointer to our new stringbuilder class.
EndProcedure

Procedure sbClear(*inSBClass.StringBuilder)
   ;
   If *inSBClass\InitDone
      FreeMemory(*inSBClass\pString)
      *inSBClass\pString = 0
      *inSBClass\StringSize = 0
      *inSBClass\BlockSize = 0
      *inSBClass\InitDone = #False
      *inSBClass\MemSize = 0
   EndIf
   ;
EndProcedure

Procedure sbDestroy(*inSBClass.StringBuilder)
   ;
   If *inSBClass\InitDone
      FreeMemory(*inSBClass\pString)
      *inSBClass\pString = 0
      *inSBClass\StringSize = 0
      *inSBClass\BlockSize = 0
      *inSBClass\InitDone = #False
      *inSBClass\MemSize = 0
   EndIf
   ;
   FreeMemory(*inSBClass)
   ;
EndProcedure

Procedure sbAdd(*inSBClass.StringBuilder, inString.l)
   ;
   Protected StrLen.l
   Protected pNewString.l
   Protected NewMemSize.l
   Protected NewStringSize.l
   ;
   StrLen = MemoryStringLength(inString)
   ;
   NewStringSize = StrLen + *inSBClass\StringSize
   ;
   If NewStringSize + 1 > *inSBClass\MemSize
      NewMemSize = *inSBClass\MemSize + *inSBClass\BlockSize
      pNewString=AllocateMemory(NewMemSize)
      If pNewString = 0 : ProcedureReturn #False : EndIf
      CopyMemory(*inSBClass\pString, pNewString, *inSBClass\StringSize)
      FreeMemory(*inSBClass\pString)
      *inSBClass\pString = pNewString
      *inSBClass\MemSize = NewMemSize
   EndIf
   ;
   CopyMemory(inString, *inSBClass\pString + *inSBClass\StringSize, StrLen)
   *inSBClass\StringSize = NewStringSize
   ;
EndProcedure

Procedure sbAddLiteral(*inSBClass.StringBuilder, inString.s)
   ;
   Protected sAddress.l
   Protected StrLen.l
   Protected pNewString.l
   Protected NewMemSize.l
   Protected NewStringSize.l
   ;
   sAddress = @inString
   StrLen = MemoryStringLength(sAddress)
   ;
   NewStringSize = StrLen + *inSBClass\StringSize
   ;
   If NewStringSize + 1 > *inSBClass\MemSize
      NewMemSize = *inSBClass\MemSize + *inSBClass\BlockSize
      pNewString=AllocateMemory(NewMemSize)
      If pNewString = 0 : ProcedureReturn #False : EndIf
      CopyMemory(*inSBClass\pString, pNewString, *inSBClass\StringSize)
      FreeMemory(*inSBClass\pString)
      *inSBClass\pString = pNewString
      *inSBClass\MemSize = NewMemSize
   EndIf
   ;
   CopyMemory(sAddress, *inSBClass\pString + *inSBClass\StringSize, StrLen)
   *inSBClass\StringSize = NewStringSize
   ;
EndProcedure

Procedure.s sbGetString(*inSBClass.StringBuilder)
   ;
   Protected WholeString.s
   ;
   WholeString = PeekS(*inSBClass\pString)
   ;
   ProcedureReturn WholeString
   ;
EndProcedure

Procedure.s sbGetStringAndDestroy(*inSBClass.StringBuilder)
   ;
   Protected WholeString.s
   ;
   WholeString = PeekS(*inSBClass\pString)
   sbDestroy(*inSBClass)
   ;
   ProcedureReturn WholeString
   ;
EndProcedure

Procedure.l sbLength(*inSBClass.StringBuilder)
  Protected iLength.l
  iLength = *inSBClass\StringSize
  ProcedureReturn iLength
EndProcedure

Start = ElapsedMilliseconds()
sHold.s = "1"
sDelimiter.s = Chr(13)+Chr(10)
q.l = sbCreate(2048)
; Create a new string builder with a blocksize of 2048.  You can create as many as you like.  Just use a new long variable and pass it as a reference to the various functions.

For Inc = 0 To 180000
sbAdd(q, @sHold)
; Add a string by the address of the string variable
sbAdd(q, @sDelimiter)
sbAddLiteral(q, "Hi!")
Next
; Add by string rather than string address.
Debug sbGetString(q)
; Return the string itself
Debug "Length: "+Str(sbLength(q))
; Return the character count - 1 based. So "Hi" will return 2.  Our example here should return 5.
sbDestroy(q)
; Destroy the string builder and clean up the used memory.
Debug ElapsedMilliseconds() - Start


Start = ElapsedMilliseconds()
sContent.s = ""
For Inc = 0 To 180000
  sContent + sHold
  sContent + sDelimiter
  sContent + "Hi!"
Next
Debug sContent
Debug "Length: "+Str(Len(sContent))
Debug ElapsedMilliseconds() - Start
Avec d'assez bons résultats :

Code : Tout sélectionner

Length: 1080006
578 ms
Length: 1080006
658938 ms
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

C'est décidé, je kiffe ce code ! Trop puissant !!!!!!!!
Répondre