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
Donc comment pourrais je optimiser ca ?
Code : Tout sélectionner
ForEach LL_Lines()
If LL_Lines()\function = LL_DLLFunctions()\FuncName
sASMContent + LL_Lines()\line + #System_EOL
EndIf
Next
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)
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é).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...
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
Code : Tout sélectionner
Length: 1080006
578 ms
Length: 1080006
658938 ms