Page 1 of 2

Repeat / dupplicate a string

Posted: Fri Jul 03, 2020 12:18 pm
by Olli

Code: Select all

Procedure.S RepStr(A$, N.I = 1)
   Define R$, I
   For I = 1 To N
      R$ + A$
   Next
   ProcedureReturn R$
EndProcedure
Example :

Code: Select all

Debug RepStr("ha", 3)
; Displays "hahaha"

Re: Repeat / dupplicate a string

Posted: Fri Jul 03, 2020 12:23 pm
by BarryG
You can do this until the team decides whether to add your request. It's much faster than building a string with For/Next, and doesn't have the overhead of a procedure.

Code: Select all

Macro RepStr(text,num)
  ReplaceString(Space(num)," ",text)
EndMacro

Debug RepStr("ha",3) ; Displays "hahaha"

Re: Repeat / dupplicate a string

Posted: Fri Jul 03, 2020 1:11 pm
by Olli
Clever !

Re: Repeat / dupplicate a string

Posted: Fri Jul 03, 2020 1:30 pm
by NicTheQuick
It would be phenomenal to overload the * operator for this like so:

Code: Select all

Debug "ha" * 3 ;outputs "hahaha"
But maybe I am just a little bit influenced by years of working with Python. :lol:

Re: Repeat / dupplicate a string

Posted: Fri Jul 03, 2020 5:06 pm
by Olli
How is interpreted

Code: Select all

"ha" * "hi"
1) "ha" ?
2) "hi" ?
3) "haha" ?
4) "hihi" ?
5) error ?

Re: Repeat / dupplicate a string

Posted: Fri Jul 03, 2020 5:18 pm
by NicTheQuick

Code: Select all

>>> "ha" * "hi"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'str'

Re: Repeat / dupplicate a string

Posted: Fri Jul 03, 2020 8:57 pm
by kenmo
You can do this until the team decides whether to add your request. It's much faster than building a string with For/Next, and doesn't have the overhead of a procedure.
Nice simple one-liner :)

Now you got me interested, here's a procedure which seems to be faster than the Macro (surely it varies with the input and output lengths, though)

Code: Select all

Procedure.S RepStr(A$, N.I = 1)
   Define R$, I
   For I = 1 To N
      R$ + A$
   Next
   ProcedureReturn R$
EndProcedure

Macro RepStr2(text,num)
  ReplaceString(Space(num)," ",text)
EndMacro

Procedure.s RepStr3(A$, N.I = 1)
  Protected R$
  If A$ = ""
  ElseIf (N > 1)
    R$ = A$ + Space(Len(A$) * (N-1))
    Copied = StringByteLength(A$)
    Remain = Copied * (N-1)
    While (#True)
      If (Remain > Copied)
        CopyMemory(@R$, @R$ + Copied, Copied)
        Remain - Copied
        Copied + Copied
      Else
        CopyMemory(@R$, @R$ + Copied, Remain)
        Break
      EndIf
    Wend
  ElseIf (N = 1)
    R$ = A$
  EndIf
  ProcedureReturn R$
EndProcedure

CompilerIf #PB_Compiler_Debugger
  CompilerError "Turn off Debugger for accurate speed comparison"
CompilerEndIf

OpenConsole()

TestStr.s = "ha"
NumRepeats.i = 5000

UseMD5Fingerprint()

PrintN("Method 1")
NumLoops.i = 10 ; limit the number of loops because this method is much slower!
Start = ElapsedMilliseconds()
For j = 1 To NumLoops
  Test$ = RepStr(TestStr, NumRepeats)
Next j
Stop = ElapsedMilliseconds()
PrintN(StrF((Stop - Start)/NumLoops, 3) + " ms per loop")
PrintN("Hash: " + Fingerprint(@Test$, StringByteLength(Test$), #PB_Cipher_MD5))
PrintN("")

PrintN("Method 2")
NumLoops = 1000
Start = ElapsedMilliseconds()
For j = 1 To NumLoops
  Test$ = RepStr2(TestStr, NumRepeats)
Next j
Stop = ElapsedMilliseconds()
PrintN(StrF((Stop - Start)/NumLoops, 3) + " ms per loop")
PrintN("Hash: " + Fingerprint(@Test$, StringByteLength(Test$), #PB_Cipher_MD5))
PrintN("")

PrintN("Method 3")
NumLoops = 1000
Start = ElapsedMilliseconds()
For j = 1 To NumLoops
  Test$ = RepStr3(TestStr, NumRepeats)
Next j
Stop = ElapsedMilliseconds()
PrintN(StrF((Stop - Start)/NumLoops, 3) + " ms per loop")
PrintN("Hash: " + Fingerprint(@Test$, StringByteLength(Test$), #PB_Cipher_MD5))
PrintN("")

Input()
CloseConsole()

Re: Repeat / dupplicate a string

Posted: Fri Jul 03, 2020 9:25 pm
by helpy
If you use longer strings, than the macro is the fastest ...

Re: Repeat / dupplicate a string

Posted: Fri Jul 03, 2020 11:29 pm
by kenmo
Seems to be true! I'm impressed by ReplaceString() :o

I only used a sample size of 1 string :)

Re: Repeat / dupplicate a string

Posted: Sat Jul 04, 2020 8:25 am
by Little John
By the way ... In case you just want to repeat 1 character you can use the following, which is very fast:

Code: Select all

Macro RepeatChar (_count_, _char_)
   LSet("", _count_, _char_)
EndMacro

Re: Repeat / dupplicate a string

Posted: Sat Jul 04, 2020 12:14 pm
by mk-soft
BarryG wrote:You can do this until the team decides whether to add your request. It's much faster than building a string with For/Next, and doesn't have the overhead of a procedure.

Code: Select all

Macro RepStr(text,num)
  ReplaceString(Space(num)," ",text)
EndMacro

Debug RepStr("ha",3) ; Displays "hahaha"
Optimize for big strings. First parameter allocate now enough space for the result string :wink:

Code: Select all

Macro RepBigStr(text,num)
  ReplaceString(Space(num * Len(text)), Space(Len(text)), text)
EndMacro

r1.s = RepBigStr("No12345678",3) ; Displays "hahaha"
Debug r1

Re: Repeat / dupplicate a string

Posted: Sat Jul 04, 2020 12:27 pm
by BarryG
mk-soft, what do you mean? My example works with large strings.

Code: Select all

Macro RepBigStr(text,num)
  ReplaceString(Space(num)," ",text)
EndMacro

r1.s = RepBigStr("1234567890",1000)
Debug r1
Debug Len(r1) ; 10000, as expected.

Re: Repeat / dupplicate a string

Posted: Sat Jul 04, 2020 12:33 pm
by mk-soft
With you the empty string is at first only three characters large when num = 3, and must be increased each time the string 'text' is replaced.

I don't know if this works faster, because the search string is bigger when replacing the string 'text'.

Re: Repeat / dupplicate a string

Posted: Sat Jul 04, 2020 12:39 pm
by BarryG
I think I once read that ReplaceString is very fast and optimized anyway. Even with 100000 repeats it's instant, with no pre-padding needed.

Code: Select all

RepBigStr("1234567890",100000)
[Edit] Found it -> viewtopic.php?p=244260#p244260

Re: Repeat / dupplicate a string

Posted: Sat Jul 04, 2020 12:45 pm
by mk-soft
Thats right,

Is no longer measurable on my CPU anyway. :D
Intel(R) Core(TM) i7-8700B CPU @ 3.20GHz