Fast string
Re: Fast string
I know that I'm somehow "old fashioned", but I think it is upon the developer to understand, at least in a basic form, how strings are working. And if I find such a scenario, I do it like this since 30 years now:
While the initial function in the first thread takes me 48 seconds to complete, the 6 additional lines enhanced the speed to be 0.38 seconds. This is simple to use and really helpful. I do it like this all the time when I concatenate lager strings.
It is definitely not the fastest way possible, but solved it for me cross platform and reliable.
Kukulkan
Code: Select all
DisableDebugger
Str.s
Dummy.s
#Text = "1234567890"
Time = ElapsedMilliseconds()
For i=1 To 100000
Dummy + #Text
If Len(Dummy) > 2048
Str + Dummy
Dummy = ""
EndIf
Next i
Str + Dummy
MessageRequester("", StrF((ElapsedMilliseconds()-Time)/1000, 3))
It is definitely not the fastest way possible, but solved it for me cross platform and reliable.
Kukulkan
Re: Fast string
Thanks for that example.
I like solutions where things are easy and fast and not only "fastest as possible even hard to implement".
What speed factors do we talk about?
- naive string handling
- Kukulkans less memory mappings method
- fast string builder
(It's about huge strings, isn't it?)
And... I can not see the problem.
Shouldn't it be possible in any situation (CSV, etc.) to guess the max size of the string and use Space() and PokeS?
Another shrink is then one fast memory operation.
I like solutions where things are easy and fast and not only "fastest as possible even hard to implement".
What speed factors do we talk about?
- naive string handling
- Kukulkans less memory mappings method
- fast string builder
(It's about huge strings, isn't it?)
And... I can not see the problem.
Shouldn't it be possible in any situation (CSV, etc.) to guess the max size of the string and use Space() and PokeS?
Another shrink is then one fast memory operation.
Re: Fast string
Just a little fun code, to remember this is still a thing
Result
Code: Select all
EnableExplicit
Procedure StringAppend(*sb,string.s)
Protected size,*Offset
If *sb
size=MemorySize(*sb)
*Offset=size
EndIf
size+StringByteLength(string)
*sb=ReAllocateMemory(*sb,size,#PB_Memory_NoClear)
PokeS(*sb+*offset,string,-1,#PB_String_NoZero)
ProcedureReturn *sb
EndProcedure
Procedure.s SBToString(*sb)
ProcedureReturn PeekS(*sb,MemorySize(*sb)/SizeOf(Character))
EndProcedure
OpenConsole()
Define i
Define s.s="Lalala"
Define *sb=StringAppend(*sb,"Lalala")
#max=100000
Define start=ElapsedMilliseconds()
For i=1 To #max
s+"La"
Next
Define ende=ElapsedMilliseconds()
PrintN(Str(ende-start)+" - "+Len(s))
start=ElapsedMilliseconds()
For i=1 To #max
*sb=StringAppend(*sb,"La")
Next
ende=ElapsedMilliseconds()
PrintN(Str(ende-start)+" - "+Len(SBToString(*sb)))
Input()
CloseConsole()
Code: Select all
40733 - 200006
23 - 200006
Re: Fast string
I have an issue with extremely slow strings, that I posted about here:Cyllceaux wrote:Just a little fun code, to remember this is still a thing
http://www.purebasic.fr/english/viewtop ... 13&t=70568
I'd love to see strings being fast natively, to avoid POKES and memory buffers and mucking around like that.
Technically, no. But if we can write long blocks of code as a "workaround", then such workarounds need to become native.Shield wrote:This is not generally a PureBasic "problem"
- marcoagpinto
- Addict
- Posts: 940
- Joined: Sun Mar 10, 2013 3:01 pm
- Location: Portugal
- Contact:
Re: Fast string
To build a 505 KB string, it's literally faster to use a ListIconGadget and a disk write/read, than to build it the traditional way
Code: Select all
Debug "Please wait, speed testing..."
DisableDebugger
OpenWindow(0,200,200,200,100,"test",#PB_Window_Invisible)
ListIconGadget(0,10,10,180,80,"test",180)
; Prep the ListIconGadget with 505 KB of text:
items=5000
For a=1 To items
AddGadgetItem(0,-1,Str(a)+Space(100))
Next
; Build a 505 KB string directly from the gadget:
start.q=ElapsedMilliseconds()
For a=1 To items
one$+GetGadgetItemText(0,a)
Next
one.q=ElapsedMilliseconds()-start
; Build another 505 KB string using disk access:
start.q=ElapsedMilliseconds()
f$=GetTemporaryDirectory()+"string-speed-test"
If CreateFile(0,f$)
For a=1 To items
WriteString(0,GetGadgetItemText(0,a))
Next
CloseFile(0)
If ReadFile(0,f$)
two$=ReadString(0,#PB_File_IgnoreEOL)
CloseFile(0)
EndIf
DeleteFile(f$)
EndIf
two.q=ElapsedMilliseconds()-start
; The results:
EnableDebugger
Debug "Len(one$)="+Str(Len(one$))+" and took "+Str(one)+" ms" ; 8216 ms (8 seconds!)
Debug "Len(two$)="+Str(Len(two$))+" and took "+Str(two)+" ms" ; 22 ms (not even a quarter of a second!)
- the.weavster
- Addict
- Posts: 1537
- Joined: Thu Jul 03, 2003 6:53 pm
- Location: England
Re: Fast string
Dude's test made me wonder how fast it would be to add strings you want to concatenate to a list and then iterate over that list and copy each item into a memory block and then PeekS() at the outcome.
I've finessed that idea slightly and here's the result:
Copying Dude's test (but with a delimiter so I can split the string again) I get:
Join 8ms
Split 31ms
Edit: Tweaked to add procedures to insert, remove, replace and get longest in order to handle this.
I've finessed that idea slightly and here's the result:
Code: Select all
DisableDebugger
Structure StringBuilderItem
item.s
size.i
EndStructure
Structure StringBuilder
size.i
count.i
List item.StringBuilderItem()
EndStructure
Procedure StringBuilder_Add(*sb.StringBuilder,itm$)
nSize = StringByteLength(itm$)
*sb\size = *sb\size + nSize
*sb\count = *sb\count + 1
AddElement(*sb\item())
*sb\item()\item = itm$
*sb\item()\size = nSize
EndProcedure
Procedure StringBuilder_Clear(*sb.StringBuilder)
ClearList(*sb\item())
*sb\count = 0
*sb\size = 0
EndProcedure
Procedure StringBuilder_Free(*sb.StringBuilder)
ClearList(*sb\item())
FreeStructure(*sb)
EndProcedure
Procedure.s StringBuilder_Get(*sb.StringBuilder,idx.i)
If idx > *sb\count - 1
ProcedureReturn ""
EndIf
SelectElement(*sb\item(),idx)
ProcedureReturn *sb\item()\item
EndProcedure
Procedure.s StringBuilder_GetChunk(*source,nSize)
*bfr = AllocateMemory(nSize + 4)
CopyMemory(*source,*bfr,nSize)
out$ = PeekS(*bfr)
FreeMemory(*bfr)
ProcedureReturn out$
EndProcedure
Procedure.i StringBuilder_GetLongest(*sb.StringBuilder)
nLongest = 0
ResetList(*sb\item())
While NextElement(*sb\item())
If *sb\item()\size > nLongest
nLongest = *sb\item()\size
EndIf
Wend
ProcedureReturn nLongest
EndProcedure
Procedure StringBuilder_Insert(*sb.StringBuilder,idx,val$)
If idx > *sb\count - 1 : ProcedureReturn : EndIf
SelectElement(*sb\item(),idx)
InsertElement(*sb\item())
nSize = StringByteLength(val$)
*sb\count = *sb\count + 1
*sb\size = *sb\size + nSize
*sb\item()\item = val$
*sb\item()\size = nSize
EndProcedure
Procedure.s StringBuilder_Join(*sb.StringBuilder,delim$="")
nSizeDelim = StringByteLength(delim$)
nAdder = ListSize(*sb\item()) * nSizeDelim
*bfr = AllocateMemory(*sb\size + nAdder + 4)
nLoops = 0
ResetList(*sb\item())
While NextElement(*sb\item())
PokeS(*bfr+nPos,*sb\item()\item,*sb\item()\size)
nPos = nPos + *sb\item()\size
nLoops = nLoops + 1
If nSizeDelim > 0 And nLoops < *sb\count
PokeS(*bfr+nPos,delim$,nSizeDelim)
nPos = nPos + nSizeDelim
EndIf
Wend
out$ = PeekS(*bfr,*sb\size)
FreeMemory(*bfr)
ProcedureReturn out$
EndProcedure
Procedure.i StringBuilder_New()
*s.StringBuilder = AllocateStructure(StringBuilder)
*s\count = 0
*s\size = 0
ProcedureReturn *s
EndProcedure
Procedure StringBuilder_Remove(*sb.StringBuilder,idx.i)
If idx > *sb\count - 1 : ProcedureReturn : EndIf
SelectElement(*sb\item(),idx)
*sb\count = *sb\count - 1
*sb\size = *sb\size - *sb\item()\size
DeleteElement(*sb\item())
EndProcedure
Procedure StringBuilder_Replace(*sb.StringBuilder,idx.i,val$)
If idx > *sb\count - 1 : ProcedureReturn : EndIf
SelectElement(*sb\item(),idx)
*sb\size = *sb\size - *sb\item()\size
nSize = StringByteLength(val$)
*sb\size = *sb\size + nSize
*sb\item()\item = val$
*sb\item()\size = nSize
EndProcedure
Procedure.i StringBuilder_Split(val$,delim$)
*sb = StringBuilder_New()
nSizeDel = StringByteLength(delim$)
nSizeVal = StringByteLength(val$)
If nSizeDel = 0 Or nSizeVal = 0
ProcedureReturn *sb
EndIf
nEnd = 0 : nLen = 0 : nStart = 0
While nEnd <= nSizeVal
If CompareMemory(@val$+nEnd,@delim$,nSizeDel)
StringBuilder_Add(*sb,StringBuilder_GetChunk(@val$+nStart,nLen))
nEnd = nEnd + nSizeDel
nStart = nEnd
nLen = 0
Else
nEnd = nEnd + 1
nLen = nLen + 1
EndIf
Wend
If nLen > 0
StringBuilder_Add(*sb,StringBuilder_GetChunk(@val$+nStart,nLen))
EndIf
ProcedureReturn *sb
EndProcedure
items=5000
joinstart.q=ElapsedMilliseconds()
*s.StringBuilder = StringBuilder_New()
For a=1 To items
StringBuilder_Add(*s,Str(a)+Space(100))
Next
s$=StringBuilder_Join(*s,"|")
joinend.q=ElapsedMilliseconds()-joinstart
splitstart.q=ElapsedMilliseconds()
*s1.StringBuilder = StringBuilder_Split(s$,"|")
splitend.q=ElapsedMilliseconds()-splitstart
EnableDebugger
Debug "Join: Len(s$)= "+Str(Len(s$))+" and took "+Str(joinend)+" ms"
Debug "Split: Elements(s$)= "+Str(*s1\count)+" and took "+Str(splitend)+" ms"
StringBuilder_Free(*s)
StringBuilder_Free(*s1)
s$ = "Probably the best sparkling wine in the world"
*s.StringBuilder = StringBuilder_Split(s$," ")
StringBuilder_Replace(*s,3,"malt")
StringBuilder_Remove(*s,4)
StringBuilder_Insert(*s,4,"vinegar")
Debug StringBuilder_Join(*s," ")
Join 8ms
Split 31ms
Edit: Tweaked to add procedures to insert, remove, replace and get longest in order to handle this.
Re: Fast string
@Kukulkan: your code below is magic! I have no idea how it works, but it lets me build a 386 KB string (a list of 9895 filenames in a folder, with 40 characters per name) in just 390 ms! Thank you!
So, what's with the 2048 size test? Can you explain how that works? When I halved it to 1024, the routine was slower; and when I doubled it to 4096, my app crashed with an illegal memory access error. So 2048 seems to be the sweet-spot.
So, what's with the 2048 size test? Can you explain how that works? When I halved it to 1024, the routine was slower; and when I doubled it to 4096, my app crashed with an illegal memory access error. So 2048 seems to be the sweet-spot.
Code: Select all
For i=1 To 100000
Dummy + #Text
If Len(Dummy) > 2048
Str + Dummy
Dummy = ""
EndIf
Next i
Str + Dummy
-
- Enthusiast
- Posts: 334
- Joined: Mon Feb 04, 2013 5:28 pm
Re: Fast string
Yes, stringbuilders in PB and strings prepended with the actual length would be useful language additions.
So ...
So ...
Re: Fast string
@Cyllceaux
When I want to use your procedures in a loop but build different strings on each iteration,
how do I "reset" it?
after each iteration won't work...
Code: Select all
Procedure StringAppend(*sb,string.s)
Protected size,*Offset
If *sb
size=MemorySize(*sb)
*Offset=size
EndIf
size+StringByteLength(string)
*sb=ReAllocateMemory(*sb,size,#PB_Memory_NoClear)
PokeS(*sb+*offset,string,-1,#PB_String_NoZero)
ProcedureReturn *sb
EndProcedure
Procedure.s SBToString(*sb)
ProcedureReturn PeekS(*sb,MemorySize(*sb)/SizeOf(Character))
EndProcedure
how do I "reset" it?
Code: Select all
FreeMemory(*sb)
-
- Enthusiast
- Posts: 237
- Joined: Tue Feb 14, 2017 12:07 pm
Re: Fast string
Code: Select all
Structure MyStringBuilder
*MyStringBuilderMemoryiD
MyStringBuilderSize.q
MyStringBuilderRemaining.q
MyStringBuilderPosition.q
EndStructure
Global Dim MyStringBuilder.MyStringBuilder(0)
Procedure.b initialiseStringBuilder(Taille.q)
If Taille.q <= 0
Taille.q = 1
EndIf
If ArraySize(MyStringBuilder(), 1) = -1
ProcedureReturn 0
EndIf
If MyStringBuilder.MyStringBuilder(0)\MyStringBuilderMemoryiD = 0
*MyStringBuilderMemoryiD = AllocateMemory(StringByteLength(Space(Taille.q), #PB_Unicode) + 2)
If *MyStringBuilderMemoryiD
MyStringBuilder.MyStringBuilder(0)\MyStringBuilderMemoryiD = *MyStringBuilderMemoryiD
MemorySize.q = MemorySize(MyStringBuilder.MyStringBuilder(0)\MyStringBuilderMemoryiD) / 2
MemorySize.q - 1
MyStringBuilder.MyStringBuilder(0)\MyStringBuilderRemaining = MemorySize.q
MyStringBuilder.MyStringBuilder(0)\MyStringBuilderSize = MemorySize.q
MyStringBuilder.MyStringBuilder(0)\MyStringBuilderPosition = 0
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure.b isStringBuilder(ElementiD.i)
ArraySize.i = ArraySize(MyStringBuilder(), 1)
If ArraySize.i = -1 Or ElementiD.i < 0 Or ElementiD.i > ArraySize.i
ProcedureReturn 0
EndIf
If MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderMemoryiD <> 0
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure.b StringBuilderAddElement(Taille.q)
ArraySize.i = ArraySize(MyStringBuilder(), 1)
If ArraySize.i = -1
ProcedureReturn 0
EndIf
ReDim MyStringBuilder.MyStringBuilder(ArraySize.i + 1)
*MyStringBuilderMemoryiD = AllocateMemory(StringByteLength(Space(Taille.q), #PB_Unicode) + 2)
If *MyStringBuilderMemoryiD
MyStringBuilder.MyStringBuilder(ArraySize.i + 1)\MyStringBuilderMemoryiD = *MyStringBuilderMemoryiD
MemorySize.q = MemorySize(MyStringBuilder.MyStringBuilder(ArraySize.i + 1)\MyStringBuilderMemoryiD) / 2
MemorySize.q - 1
MyStringBuilder.MyStringBuilder(ArraySize.i + 1)\MyStringBuilderRemaining = MemorySize.q
MyStringBuilder.MyStringBuilder(ArraySize.i + 1)\MyStringBuilderSize = MemorySize.q
MyStringBuilder.MyStringBuilder(ArraySize.i + 1)\MyStringBuilderPosition = 0
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
ProcedureReturn ElementiD.i + 1
EndProcedure
Procedure.b StringBuilderClearString(ElementiD.i)
If Not isStringBuilder(ElementiD.i)
ProcedureReturn 0
EndIf
MemorySize.q = MemorySize(MyStringBuilder.MyStringBuilder(ArraySize.i + 1)\MyStringBuilderMemoryiD) / 2
MemorySize.q - 1
FillMemory(MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderMemoryiD, MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderSize, #Null , #PB_Unicode)
MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderRemaining = MemorySize.q
MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderSize = MemorySize.q
MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderPosition = 0
ProcedureReturn 1
EndProcedure
Procedure.b StringBuilderReAllocate(ElementiD.i, Taille.q)
If Taille.q <= 0
Taille.q = 1
EndIf
If Not isStringBuilder(ElementiD.i)
ProcedureReturn 0
EndIf
*MyStringBuilderMemoryiD = ReAllocateMemory(MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderMemoryiD, Taille.q)
If *MyStringBuilderMemoryiD
MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderMemoryiD = *MyStringBuilderMemoryiD
MemorySize.q = MemorySize(MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderMemoryiD) / 2
MemorySize.q - 1
TailleActuel.q = MemorySize.q
NouvelleTaille.q = Taille.q
Restant.q = MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderRemaining
If TailleActuel.q > NouvelleTaille.q
Difference.q = TailleActuel.q - NouvelleTaille.q
Restant.q - Difference.q
If Restant.q < 0
MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderPosition + Restant.q
Restant.q = 0
EndIf
MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderRemaining = Restant.q
MyStringBuilder.MyStringBuilder(ArraySize.i + 1)\MyStringBuilderSize = Taille.q
ElseIf NouvelleTaille.q > TailleActuel.q
Difference.q = NouvelleTaille.q - TailleActuel.q
Restant.q + Difference.q
MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderRemaining = Restant.q
MyStringBuilder.MyStringBuilder(ArraySize.i + 1)\MyStringBuilderSize = Taille.q
EndIf
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure.b StringBuilderAddString(ElementiD.i, String.s)
If Not String.s > ""
ProcedureReturn 0
EndIf
If isStringBuilder(ElementiD.i)
If Len(String.s) > MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderRemaining
*MyStringBuilderMemoryiD = ReAllocateMemory(MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderMemoryiD, MemorySize(MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderMemoryiD) + (StringByteLength(String.s) * 10))
If *MyStringBuilderMemoryiD
MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderMemoryiD = *MyStringBuilderMemoryiD
MemorySize.q = MemorySize(MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderMemoryiD) / 2
MemorySize.q - 1
If PokeS(MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderMemoryiD + (MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderPosition * 2), String.s, -1, #PB_Unicode)
MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderRemaining = MemorySize.q - MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderPosition - Len(String.s)
MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderSize = MemorySize.q
MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderPosition + Len(String.s)
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
Else
ProcedureReturn 0
EndIf
Else
MemorySize.q = MemorySize(MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderMemoryiD) / 2
MemorySize.q - 1
If PokeS(MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderMemoryiD + (MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderPosition * 2), String.s, -1, #PB_Unicode)
MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderRemaining = MemorySize.q - MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderPosition - Len(String.s)
MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderSize = MemorySize.q
MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderPosition + Len(String.s)
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndIf
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure.S StringBuilderGetString(ElementiD.i)
If isStringBuilder(ElementiD.i)
ProcedureReturn PeekS(MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderMemoryiD, -1, #PB_Unicode)
Else
ProcedureReturn ""
EndIf
EndProcedure
Procedure.i StringBuilderGetMemoryiD(ElementiD.i)
If isStringBuilder(ElementiD.i)
ProcedureReturn MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderMemoryiD
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure.i StringBuilderGetMemorySize(ElementiD.i)
If isStringBuilder(ElementiD.i)
ProcedureReturn MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderSize
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure.i StringBuilderGetMemoryRemaining(ElementiD.i)
If isStringBuilder(ElementiD.i)
ProcedureReturn MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderRemaining
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure.i StringBuilderGetMemoryPosition(ElementiD.i)
If isStringBuilder(ElementiD.i)
ProcedureReturn MyStringBuilder.MyStringBuilder(ElementiD.i)\MyStringBuilderPosition
Else
ProcedureReturn 0
EndIf
EndProcedure
;
; Procedure.i StringBuilderDeletteElement()
;
;
;
; EndProcedure
;
; Procedure.i StringBuilderCopyElement()
;
;
;
; EndProcedure
Abc$ = "Abcdefghijklmnopqrstuvwxyz"
If initialiseStringBuilder(0)
For MonStringBuilder1.i = 0 To 5
If isStringBuilder(MonStringBuilder1.i)
MessageRequester("StringBuilder initialisation...", "StringBuilderID = " + Str(MonStringBuilder1.i) + Chr(13) + Chr(10) +
"StringBuilder MemoryiD = " + Str(StringBuilderGetMemoryiD(MonStringBuilder1.i)) + Chr(13) + Chr(10) +
"StringBuilder Memory Size = " + Str(StringBuilderGetMemorySize(MonStringBuilder1.i)) + Chr(13) + Chr(10) +
"StringBuilder Memory Remaining = " + Str(StringBuilderGetMemoryRemaining(MonStringBuilder1.i)) + Chr(13) + Chr(10) +
"StringBuilder Memory Position = " + Str(StringBuilderGetMemoryPosition(MonStringBuilder1.i)))
Time1 = ElapsedMilliseconds()
For i = 1 To 255
Write.b = StringBuilderAddString(MonStringBuilder1.i, Abc$)
MemoryiD.q = StringBuilderGetMemoryiD(MonStringBuilder1.i)
MemorySize.q = StringBuilderGetMemorySize(MonStringBuilder1.i)
MemoryRemaining.q = StringBuilderGetMemoryRemaining(MonStringBuilder1.i)
MemoryPosition.q = StringBuilderGetMemoryPosition(MonStringBuilder1.i)
;
; Debug "MemoryiD: " + Str(MemoryiD.q)
; Debug "MemorySize: " + Str(MemorySize.q)
; Debug "MemoryRemaining: " + Str(MemoryRemaining.q)
; Debug "MemoryPosition: " + Str(MemoryPosition.q)
; Debug "Write: " + Str(Write.b)
; Debug "---------------------------"
;
Next
Time2 = ElapsedMilliseconds()
MessageRequester("StringBuilder Résultat...", "StringBuilderID = " + Str(MonStringBuilder1.i) + Chr(13) + Chr(10) +
"StringBuilder MemoryiD = " + Str(StringBuilderGetMemoryiD(MonStringBuilder1.i)) + Chr(13) + Chr(10) +
"StringBuilder Memory Size = " + Str(StringBuilderGetMemorySize(MonStringBuilder1.i)) + Chr(13) + Chr(10) +
"StringBuilder Memory Remaining = " + Str(StringBuilderGetMemoryRemaining(MonStringBuilder1.i)) + Chr(13) + Chr(10) +
"StringBuilder Memory Position = " + Str(StringBuilderGetMemoryPosition(MonStringBuilder1.i)) + Chr(13) + Chr(10) +
"Time Elapsed = " + Str(Time2 - Time1) + " Ms.")
If StringBuilderAddElement(1)
Else
Debug 0
EndIf
Else
MessageRequester("StringBuilder Résultat...", "Erreur, Le StringBuilder n°" + Str(MonStringBuilder1.i) + ", n'a pas put être initialisé !", 16)
EndIf
Next
Else
MessageRequester("StringBuilder Résultat...", "Erreur, Le StringBuilder n'a pas put être initialisé !", 16)
EndIf
For i = 0 To 5
Debug StringBuilderGetString(I)
Debug "----------"
Next
I am French, I do not speak English.
My apologies for the mistakes.
I have sometimes problems of expression
I am sometimes quite clumsy, please excuse me and let me know.
My apologies for the mistakes.
I have sometimes problems of expression
I am sometimes quite clumsy, please excuse me and let me know.
-
- Enthusiast
- Posts: 237
- Joined: Tue Feb 14, 2017 12:07 pm
Re: Fast string
Code: Select all
Structure StructureMyStringBuilder
*MyStringBuilderMemoryID
MyStringBuilderSize.q
MyStringBuilderRemaining.q
MyStringBuilderPosition.q
EndStructure
Global NewMap MapMyStringBuilder.StructureMyStringBuilder()
; Crée un nouveau StringBuilder avec comme Nom: Nom$ et Taille (En caractères): Taille.q.
; Il est conseillé de mèttre une taille assez grande pour pouvoir ajouter par la suite la ou les nouvelles Chaines de sorte à se que le programme ne sois pas obligé
; de réalouer automatiquement une taille plus grande pour pouvoir y ajouter la nouvelle Chaine, puisque ceci ralentie beaucoup le programme.
; Si le Nom est vide ou que celui-ci existe déjà alors la fonction échoura.
; Si la Taille est inférieur ou égale à 0 alors Taille vaudra 1.
; La Taille du StringBuilder est toujours en caractères.
; Renvoie 1 si le StringBuilder a été créer ou sinon 0.
Procedure.b CreateAndInitialiseMyStringBuilder(Nom$, Taille.q = 1)
If Nom$ = "" Or FindMapElement(MapMyStringBuilder(), Nom$)
ProcedureReturn 0
EndIf
If Taille.q <= 0
Taille.q = 1
EndIf
If MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID = 0
*MyStringBuilderMemoryID = AllocateMemory(StringByteLength(Space(Taille.q + 1), #PB_Unicode))
If *MyStringBuilderMemoryID
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID = *MyStringBuilderMemoryID
MemorySize.q = MemorySize(MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID) / 2
MemorySize.q - 1
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderRemaining = MemorySize.q
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderSize = MemorySize.q
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderPosition = 1
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
Else
ProcedureReturn 0
EndIf
EndProcedure
; Vérifie que le StringBuilder existe avec comme Nom: Nom$.
; Si le Nom est vide ou que celui-ci n'existe pas alors la fonction échoura.
; Renvoie 1 si le StringBuilder éxiste ou sinon 0.
Procedure.b IsMyStringBuilder(Nom$)
If Nom$ = "" Or Not FindMapElement(MapMyStringBuilder(), Nom$)
ProcedureReturn 0
Else
ProcedureReturn 1
EndIf
EndProcedure
; Ajoute une nouvelle chaine à la suite dans le StringBuilder avec comme Nom: Nom$ et Chaine: String.s.
; Si le Nom est vide ou que celui-ci n'existe pas alors la fonction échoura.
; Si la Chaine à ajouter est vide alors la fonction échoura.
; Renvoie 1 si la Chaine a été ajouté ou sinon 0.
Procedure.b MyStringBuilderAddString(Nom$, String.s)
If IsMyStringBuilder(Nom$) And String.s > ""
If Len(String.s) > MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderRemaining
*MyStringBuilderMemoryID = ReAllocateMemory(MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID, MemorySize(MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID) + (StringByteLength(String.s) * 10))
If *MyStringBuilderMemoryID
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID = *MyStringBuilderMemoryID
MemorySize.q = MemorySize(MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID) / 2
MemorySize.q - 1
If PokeS(MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID + ((MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderPosition - 1) * 2), String.s, -1, #PB_Unicode)
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderRemaining = (MemorySize.q - (MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderPosition - 1) - Len(String.s))
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderSize = MemorySize.q
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderPosition + Len(String.s)
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
Else
ProcedureReturn 0
EndIf
Else
MemorySize.q = MemorySize(MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID) / 2
MemorySize.q - 1
If PokeS(MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID + ((MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderPosition - 1) * 2), String.s, -1, #PB_Unicode)
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderRemaining = (MemorySize.q - (MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderPosition - 1) - Len(String.s))
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderSize = MemorySize.q
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderPosition + Len(String.s)
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndIf
Else
ProcedureReturn 0
EndIf
EndProcedure
; Change la Taille (En caractères) d'allocation du StringBuilder avec comme Nom: Nom$ et Taille: Taille.q.
; Attention, si la Taille spécifié est plus petite que celle actuel, la Chaine du StringBuilder à la fin de celui-ci serra alors raccourcir et ainsi, les données serront alors supprimé définitivement.
; Si le Nom est vide ou que celui-ci n'éxiste pas alors la fonction échoura.
; Si la Taille est inférieur ou égale à 0 alors Taille vaudra 1.
; La Taille du StringBuilder est toujours en caractères.
; Renvoie 1 si la Taille du StringBuilder a été changé ou sinon 0.
Procedure.b MyStringBuilderReAllocate(Nom$, Taille.q = 1)
If IsMyStringBuilder(Nom$)
If Taille.q <= 0
Taille.q = 1
EndIf
AncienneTaille.q = MemorySize(MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID) / 2
AncienneTaille.q - 1
*MyStringBuilderMemoryID = ReAllocateMemory(MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID, StringByteLength(Space(Taille.q + 1)))
If *MyStringBuilderMemoryID
PokeS(MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID + StringByteLength(Space(Taille.q)), Chr(#Null), -1, #PB_Unicode)
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID = *MyStringBuilderMemoryID
MemorySize.q = (MemorySize(MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID)) / 2
MemorySize.q - 1
TailleActuel.q = AncienneTaille.q
NouvelleTaille.q = Taille.q
Restant.q = MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderRemaining
If TailleActuel.q > NouvelleTaille.q
Difference.q = TailleActuel.q - NouvelleTaille.q
Restant.q - Difference.q
If Restant.q < 0
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderPosition + Restant.q
Restant.q = 0
EndIf
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderRemaining = Restant.q
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderSize = Taille.q
ElseIf NouvelleTaille.q > TailleActuel.q
Difference.q = NouvelleTaille.q - TailleActuel.q
Restant.q + Difference.q
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderRemaining = Restant.q
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderSize = Taille.q
EndIf
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
Else
ProcedureReturn 0
EndIf
EndProcedure
; Efface entièrement le StringBuilder avec comme Nom: Nom$.
; Si le Nom est vide ou que celui-ci n'existe pas alors la fonction échoura.
; Seule la Chaine du StringBuilder est éffacé, ça taille restera quand à elle inchangé, ceci ne supprime pas le StringBuilder.
; Renvoie 1 si le StringBuilder a été éffacé ou sinon 0.
Procedure.b MyStringBuilderClearString(Nom$)
If IsMyStringBuilder(Nom$)
MemorySize.q = MemorySize(MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID) / 2
MemorySize.q - 1
FillMemory(MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID, MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderSize, #Null , #PB_Unicode)
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderRemaining = MemorySize.q
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderSize = MemorySize.q
MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderPosition = 1
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
; Supprime le StringBuilder avec comme Nom: Nom$.
; Si le Nom est vide ou que celui-ci n'existe pas alors la fonction échoura.
; Attention, toutes les données du StringBuilder serront définitivement supprimé !
; Renvoie 1 si le StringBuilder a été supprimé ou sinon 0.
Procedure.b MyStringBuilderDeletteElement(Nom$)
If IsMyStringBuilder(Nom$)
DeleteMapElement(MapMyStringBuilder(), Nom$)
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
; Renvoie la partie de la chaine désiré du StringBuilder avec comme Nom: Nom$.
; La Position de Depart commance à 1, si celle-ci est inférieur ou égale à 0 alors celle-ci vaudra 1.
; Si la Position de Depart est supérieur à la longueur de la chaine actuellement stoqué dans le StringBuilder, alors celle-ci vaudra la longueur de la chaine actuellement stoqué dans le StringBuilder.
; La Longueur commance à 1, si celle-ci est inférieur à -1 alors celle-ci vaudra -1.
; Si la Longueur vaud -1 alors toutes la chaine stoqué dans le StringBuilder serra renvoyé.
; Si la Longueur est supérieur à la longueur de la chaine actuellement stoqué dans le StringBuilder, alors celle-ci vaudra la longueur de la chaine actuellement stoqué dans le StringBuilder.
; Si le Nom est vide ou que celui-ci n'existe pas alors la fonction renvéra une chaine vide.
Procedure.s MyStringBuilderGetString(Nom$, PositionDepart.q = 1, Longueur.q = -1)
If IsMyStringBuilder(Nom$)
If PositionDepart.q <= 1
PositionDepart.q = 1
EndIf
If PositionDepart.q > MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderSize
PositionDepart.q = MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderSize
EndIf
If Longueur.q < -1
Longueur.q = -1
EndIf
If Longueur.q > MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderSize
Longueur.q = (MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderSize)
EndIf
ProcedureReturn PeekS(MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID + ((PositionDepart.q - 1) * 2), Longueur.q, #PB_Unicode)
Else
ProcedureReturn ""
EndIf
EndProcedure
; Renvoie l'adresse mémoire ou est stoqué la chaine dans le StringBuilder avec comme Nom: Nom$.
; Si le Nom est vide ou que celui-ci n'existe pas alors la fonction renvéra 0.
Procedure.i MyStringBuilderGetMemoryID(Nom$)
If IsMyStringBuilder(Nom$)
ProcedureReturn MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderMemoryID
Else
ProcedureReturn 0
EndIf
EndProcedure
; Renvoie la Taille en caractères du StringBuilder avec comme Nom: Nom$.
; Si le Nom est vide ou que celui-ci n'existe pas alors la fonction renvéra 0.
Procedure.i MyStringBuilderGetSize(Nom$)
If IsMyStringBuilder(Nom$)
ProcedureReturn MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderSize
Else
ProcedureReturn 0
EndIf
EndProcedure
; Renvoie l'espace restant en caractères du StringBuilder avec comme Nom: Nom$.
; Si le Nom est vide ou que celui-ci n'existe pas alors la fonction renvéra 0.
Procedure.i MyStringBuilderGetRemaining(Nom$)
If IsMyStringBuilder(Nom$)
ProcedureReturn MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderRemaining
Else
ProcedureReturn 0
EndIf
EndProcedure
; Renvoie la Position en caractères du StringBuilder avec comme Nom: Nom$.
; Si le Nom est vide ou que celui-ci n'existe pas alors la fonction renvéra 0.
Procedure.i MyStringBuilderGetPosition(Nom$)
If IsMyStringBuilder(Nom$)
ProcedureReturn MapMyStringBuilder.StructureMyStringBuilder(Nom$)\MyStringBuilderPosition
Else
ProcedureReturn 0
EndIf
EndProcedure
Chaine$ = "Abcdefghijklmnopqrstuvwxyz"
Chaine2$ = ""
MyStringBuilderName$ = "MyStringBuilder n°"
Time1 = ElapsedMilliseconds()
For I = 1 To 99
If CreateAndInitialiseMyStringBuilder(MyStringBuilderName$ + Str(I), 1)
If IsMyStringBuilder(MyStringBuilderName$ + Str(I))
; MessageRequester("StringBuilder initialisation...", "StringBuilder Name = " + MyStringBuilderName$ + Str(I) + Chr(13) + Chr(10) +
; "StringBuilder MemoryID = " + Str(MyStringBuilderGetMemoryID(MyStringBuilderName$ + Str(I))) + Chr(13) + Chr(10) +
; "StringBuilder Memory Size = " + Str(MyStringBuilderGetSize(MyStringBuilderName$ + Str(I))) + Chr(13) + Chr(10) +
; "StringBuilder Memory Remaining = " + Str(MyStringBuilderGetRemaining(MyStringBuilderName$ + Str(I))) + Chr(13) + Chr(10) +
; "StringBuilder Memory Position = " + Str(MyStringBuilderGetPosition(MyStringBuilderName$ + Str(I))))
; Time1 = ElapsedMilliseconds()
For J = 1 To 255
Write.b = MyStringBuilderAddString(MyStringBuilderName$ + Str(I), Str(I) + Chaine$ + Str(J))
MemoryID.q = MyStringBuilderGetMemoryID(MyStringBuilderName$ + Str(I))
MemorySize.q = MyStringBuilderGetSize(MyStringBuilderName$ + Str(I))
MemoryRemaining.q = MyStringBuilderGetRemaining(MyStringBuilderName$ + Str(I))
MemoryPosition.q = MyStringBuilderGetPosition(MyStringBuilderName$ + Str(I))
;
; Debug "MemoryID: " + Str(MemoryID.q)
; Debug "MemorySize: " + Str(MemorySize.q)
; Debug "MemoryRemaining: " + Str(MemoryRemaining.q)
; Debug "MemoryPosition: " + Str(MemoryPosition.q)
; Debug "Write: " + Str(Write.b)
; Debug "---------------------------"
;
Next
; Time2 = ElapsedMilliseconds()
; MessageRequester("StringBuilder Résultat...", "StringBuilder Name = " + MyStringBuilderName$ + Str(I) + Chr(13) + Chr(10) +
; "StringBuilder MemoryID = " + Str(MyStringBuilderGetMemoryID(MyStringBuilderName$ + Str(I))) + Chr(13) + Chr(10) +
; "StringBuilder Memory Size = " + Str(MyStringBuilderGetSize(MyStringBuilderName$ + Str(I))) + Chr(13) + Chr(10) +
; "StringBuilder Memory Remaining = " + Str(MyStringBuilderGetRemaining(MyStringBuilderName$ + Str(I))) + Chr(13) + Chr(10) +
; "StringBuilder Memory Position = " + Str(MyStringBuilderGetPosition(MyStringBuilderName$ + Str(I))) + Chr(13) + Chr(10) +
; "Time Elapsed = " + Str(Time2 - Time1) + " Ms.")
Else
MessageRequester("StringBuilder Résultat...", "Erreur, Le StringBuilder: " + MyStringBuilderName$ + Str(I) + ", n'est pas initialisé !", 16)
EndIf
Else
MessageRequester("StringBuilder Résultat...", "Erreur, Le StringBuilder: " + MyStringBuilderName$ + Str(I) + ", n'a pas put être crée !", 16)
EndIf
Next
Time2 = ElapsedMilliseconds()
For i = 1 To 99
Debug MyStringBuilderName$ + Str(I) + " = " + MyStringBuilderGetString(MyStringBuilderName$ + Str(I))
Debug "----------"
Next
Debug "Time Elapsed = " + Str(Time2 - Time1) + " Ms."
Time1 = ElapsedMilliseconds()
; Juste 5000 au lieux des 255 * 99 = 25245
; Mettez 25245 pour voir le temps réel
For J = 1 To 5000
Chaine2$ + Str(I) + Chaine$ + Str(J)
Next
Time2 = ElapsedMilliseconds()
Debug "Time Elapsed = " + Str(Time2 - Time1) + " Ms."
; ---------------------------------------------------------------------------------Exemple 2:---------------------------------------------------------------------------------------------------------------------------------------------------
; Chaine$ = "Abcdefghijklmnopqrstuvwxyz"
; Chaine2$ = ""
; MyStringBuilderName$ = "Mon StringBuilder"
;
; Debug "Temps passé avec façon Normale = " + Str(Time2 - Time1) + " Ms."
; Debug "---------------------------------"
;
; Time1 = ElapsedMilliseconds()
;
; If CreateAndInitialiseMyStringBuilder(MyStringBuilderName$)
;
; If IsMyStringBuilder(MyStringBuilderName$)
;
; For I = 1 To 10000
; MyStringBuilderAddString(MyStringBuilderName$, Chaine$ + Str(I))
;
; Next
;
; Else
; MessageRequester("StringBuilder Résultat...", "Erreur, Le StringBuilder: " + MyStringBuilderName$ + Str(I) + ", n'est pas initialisé !", 16)
;
; EndIf
;
; Else
; MessageRequester("StringBuilder Résultat...", "Erreur, Le StringBuilder: " + MyStringBuilderName$ + Str(I) + ", n'a pas put être crée !", 16)
;
; EndIf
;
; Time2 = ElapsedMilliseconds()
;
; Debug MyStringBuilderGetString(MyStringBuilderName$)
; Debug "Temps passé avec StringBuilder = " + Str(Time2 - Time1) + " Ms."
; Debug "---------------------------------"
;
; Time1 = ElapsedMilliseconds()
;
; ; Juste 5000 au lieux des 255 * 99 = 25245
; ; Mettez 25245 pour voir le temps réel
; For J = 1 To 5000
; Chaine2$ + Str(I) + Chaine$ + Str(J)
; Next
;
; Time2 = ElapsedMilliseconds()
;
; Debug "Time Elapsed = " + Str(Time2 - Time1) + " Ms."
;
; MessageRequester("Temps", "Temps passé avec StringBuilder = " + Str(Time2 - Time1) + " Ms.", 64)
;
; ---------------------------------------------------------------------------------Exemple 3:---------------------------------------------------------------------------------------------------------------------------------------------------
; Chaine$ = "Abcdefghijklmnopqrstuvwxyz"
; Chaine2$ = ""
; MyStringBuilderName$ = "Mon StringBuilder"
; ;
; ; Time1 = ElapsedMilliseconds()
; ;
; ; For J = 1 To 10000
; ; Chaine2$ + Str(I) + Chaine$ + Str(J)
; ; Next
; ;
; ; Time2 = ElapsedMilliseconds()
; ;
; ; Debug Chaine2$
; ; Debug "Temps passé avec façon normale = " + Str(Time2 - Time1) + " Ms."
; ; Debug "---------------------------------"
;
; Time1 = ElapsedMilliseconds()
;
; If CreateAndInitialiseMyStringBuilder(MyStringBuilderName$, 100000000)
;
; If IsMyStringBuilder(MyStringBuilderName$)
;
; For I = 1 To 1000000
; MyStringBuilderAddString(MyStringBuilderName$, Chaine$ + Str(I))
;
; Next
;
; Else
; MessageRequester("StringBuilder Résultat...", "Erreur, Le StringBuilder: " + MyStringBuilderName$ + Str(I) + ", n'est pas initialisé !", 16)
;
; EndIf
;
; Else
; MessageRequester("StringBuilder Résultat...", "Erreur, Le StringBuilder: " + MyStringBuilderName$ + Str(I) + ", n'a pas put être crée !", 16)
;
; EndIf
;
; Time2 = ElapsedMilliseconds()
;
; Debug MyStringBuilderGetString(MyStringBuilderName$)
; Debug "Temps passé avec StringBuilder = " + Str(Time2 - Time1) + " Ms."
; Debug "---------------------------------"
;
; MessageRequester("Temps", "Temps passé avec StringBuilder = " + Str(Time2 - Time1) + " Ms.", 64)
I am French, I do not speak English.
My apologies for the mistakes.
I have sometimes problems of expression
I am sometimes quite clumsy, please excuse me and let me know.
My apologies for the mistakes.
I have sometimes problems of expression
I am sometimes quite clumsy, please excuse me and let me know.