Is there a Repeat method for Strings?

Did you actually test that method?

Kem, you have both, you want to know, test it and show us.

1 Like

Not sure how that was helpful. In fact, I’m sure it wasn’t.

I didn’t incentivize you to test it and get the numbers? I’m sorry for my lack of proper conversation skills. I’m really not good at it. :grinning_face_with_smiling_eyes:

Heads up, guys, Kem’s method is actually faster in higher repeat times, from about 200+ times :flushed:
Kem, you knew that, didn’t you?

OK, now we have a challenge :wink:

3 Likes

Way back when, I was just as surprised as you seem to be now. It’s the effect of doubling and re-doubling the string. (Again, this was Joe Strout’s code, and I’m guessing he did the same sorts of tests.)

There is a method that may be available in an upcoming version of Xojo that could help make it faster. I’m going to test that soon.

1 Like

As I wrote, it’s much faster than “my method” the higher the number of repetitions becomes (from about ca. 200). It takes only 16 iterations of concatenation plus a final one for 100,000 repetitions.
So, these types of discussion are great to learn something new. Thanks, Kem!

2 Likes

Moral of the story: Don’t question Kem.

5 Likes

LOL. :smiley:

But I prefer it that way, because now I understand why and how!

1 Like

Exponential approximation of the size, the inverse of logarithmic search looking for a value

.

I just tested. Repeating the letter “a” 10,000 times, and doing that 100 times, using the method in M_String vs. the potential new option yields these results in a compiled app:

M_String: 637 microsecs
Mystery method: 321 microsecs
M_String: 410 microsecs
Mystery method: 323 microsecs
M_String: 497 microsecs
Mystery method: 302 microsecs

Yes i’ve tested all versions by now and kem’s is way faster, wonder how xojo optimises internal code.

Some results:

Schermafbeelding 2022-07-06 om 09.58.58

As you can see, kem’s repeat wins by alot.
Time is in microseconds
Results on Mac M1 ARM64 native build

Nevermind this has a bug…:wink:

Public Function RepeatStr(str As String, numTimes As Integer) As String
[…]
End Function

Actually, all I expected from my original post was just “Yes, it’s this…”, or “No”. The discussion has been interesting, but now I’m confused:

“Function” only seems to occur in the documentation as part of XojoScript. So is the above intended to be XojoScript? Or is a just shorthand for the standard elements of the IDE (which of course are hard represent with just keyboard characters)?

For normal Xojo code in the IDE, you don’t put in the Function/End Function lines. The IDE does it for you. You put the function Name, Parameters, Return Type in the inspector fields for the function. If you were to copy the method from the navigator pane and past it into a text editor, you would see it in the format Rick posted. Or if you opened your text format project in a text editor, you would also see those lines.

This form is commonly used in the forum to show the full definition of a method/function. You wouldn’t paste it wholesale into the IDE. You would parse it out into its separate fields.

1 Like

Insert a Module. Name it String_Utils.

Copy all the functions codes above, 2 times, one for each function.

Since

Public Function

to

End Function

Right click the Module String_Utils in the navigator, choose paste each time.

It should create those functions there for you.

image

image

image

6 Likes

Right, I did that and it was just as you said.

Thanks!

1 Like

Now that Xojo 2022r2 has been released, I can reveal that the “mystery method” takes advantage of the new, very fast MemoryBlock.CopyBytes function.

Private Function Repeat(s As String, repetitions As Integer) As String
  if s = "" or repetitions < 1 then
    return ""
  end if
  
  if repetitions = 1 then
    return s
  end if
  
  var currentBytes as integer = s.Bytes
  var targetBytes as integer = currentBytes * repetitions
  var halfTarget as integer = targetBytes \ 2
  
  var mb as new MemoryBlock( targetBytes )
  mb.StringValue( 0, currentBytes ) = s
  
  while currentBytes <= halfTarget
    mb.CopyBytes( mb, 0, currentBytes, currentBytes )
    currentBytes = currentBytes + currentBytes
  wend
  
  var diff as integer = targetBytes - currentBytes
  if diff <> 0 then
    mb.CopyBytes( mb, 0, diff, currentBytes )
  end if
  
  return mb.StringValue( 0, targetBytes, s.Encoding )
  
End Function
4 Likes