Posts: 3,446
Threads: 376
Joined: Apr 2022
Reputation:
345
(12-26-2025, 05:15 PM)bplus Wrote: +1 Steve for doing a real timed test.
So looks like Mem stuff doesn't cut the time down in this case, like with Circle Fill timed experiments.
Too much other stuff going on behind the scenes for the mem to be quicker in this case, with this code. ASC is a plenty fast operator and does 10,000,000 swaps in 0.05 seconds here. I think that's more than fast enough for all my needs, and it's certainly much simpler to write and maintain, and understand.
Somehow it seems people tend to forget that in QB64, we can use ASC on the left hand side of the equal sign just as easily as we can on the right.
Posts: 513
Threads: 65
Joined: May 2022
Reputation:
83
Yeah, exactly—that’s why I used the word 'yet' in that post. I haven’t benchmarked it for speed yet. The ASC solution is definitely much better, no doubt about it. Whenever I see _MEM, I just think, 'Hey, you fast beast!' Well, okay, maybe not always. So, do we have a candidate for a new fast function here? Thanks for sharing. The _MEM function is crying in a corner now...
Posts: 956
Threads: 52
Joined: May 2022
Reputation:
38
12-26-2025, 06:11 PM
(This post was last modified: 12-26-2025, 07:30 PM by Kernelpanic.)
It's all quite complicated. If I understand correctly, certain characters in a new string need to be rearranged. Why not do it like this?
String strWort is reversed, and strZahl is rearranged.
PS: And that's grammatically correct too: Spiessbraten. Damn!
Code: (Select All)
'Jetzt ist es auch grammatikalisch korrekt: Spiessbraten, nicht SpiessBraten
strWortNeu = "S" + Right$(strWort, 5) + "b" + Right$(Left$(strWort, 6), 5)
Print strWortNeu
Code: (Select All)
Option _Explicit
Dim As String strWort, strWortNeu, strZahl, strZahlNeu
strWort = "Bratenspiess"
strZahl = "12345678"
Print Left$(strWort, 6)
Print Right$(strWort, 6)
Print
strWortNeu = Right$(strWort, 6) + Left$(strWort, 6)
Print strWortNeu
Print
Print strZahl
strZahlNeu = Left$(strZahl, 1) + Mid$(strZahl, 6, 1) + Mid$(strZahl, 3, 1) + Mid$(strZahl, 8, 1)
Print
Print strZahlNeu
End
Posts: 811
Threads: 128
Joined: Apr 2022
Reputation:
135
I totally forgot ASC can be used that way. Cool.
- Dav
Posts: 4,695
Threads: 222
Joined: Apr 2022
Reputation:
322
12-26-2025, 08:43 PM
(This post was last modified: 12-26-2025, 08:46 PM by bplus.)
Yes it can be done in one-line but it is ugly because it is 5 section formula that you have to manually plug in values for the positions of the 2 chars to swap.
Code: (Select All) T$ = "12345678"
' testing function to see if building correct swappings
t1$ = swapChar$(T$, 3, 6)
Print t1$ ' 12645378 check
t2$ = swapChar$(T$, 1, 8)
Print t2$ ' 82345671 check
t3$ = swapChar$(T$, 4, 5)
Print t3$ ' 12354678 check
' error 9 is past the length of s$
t4$ = swapChar$(T$, 4, 9)
Print t4$ ' no error just moved 4 to the end not terrible result ! good enough
'to do this in one line say: swap 2 and 5 as Phil had it
'T$ = Mid$(T$, 1, p1 - 1) + Mid$(T$, p2, 1) + Mid$(T$, p1 + 1, (p2 - 1) - (p1 + 1) + 1) + Mid$(T$, p1, 1) + Mid$(T$, p2 + 1)
' since p1 = 2: p2 = 5 substitute back in: 2 for p1 and 5 for p2
' OK one-liner manual substitution p1 = 2 and p2 = 5
T$ = Mid$(T$, 1, 2 - 1) + Mid$(T$, 5, 1) + Mid$(T$, 2 + 1, (5 - 1) - (2 + 1) + 1) + Mid$(T$, 2, 1) + Mid$(T$, 5 + 1)
Print T$ 'it woiked :)
'test swapChar$ function
Function swapChar$ (S$, p1, p2)
If p1 > p2 Then Swap p1, p2 'ha!
swapChar$ = Mid$(S$, 1, p1 - 1) + Mid$(S$, p2, 1) + Mid$(S$, p1 + 1, (p2 - 1) - (p1 + 1) + 1) + Mid$(S$, p1, 1) + Mid$(S$, p2 + 1)
End Function
Well that is too extreme of a thinker. If I were Phil, I would stick to what he had.
724 855 599 923 575 468 400 206 147 564 878 823 652 556 bxor cross forever
Posts: 3,446
Threads: 376
Joined: Apr 2022
Reputation:
345
12-26-2025, 09:32 PM
(This post was last modified: 12-26-2025, 09:39 PM by SMcNeill.)
For those that like a nice _MEM version of this, let me introduce the following little code snippet for you guys:
Code: (Select All)
$Console:Only
Dim As String a1, n1
a1 = "ABCDEFGHIJ" 'some strings we can swap
n1 = "1234567890"
Print a1, n1
SteveSwap a1, 2, n1, 2, 3
Print a1, n1
'some time testing
limit1 = 10000
limit2 = 1000
t1# = Timer
For i = 1 To limit1
For j = 1 To limit2
SteveSwap a1, 2, n1, 2, 3
Next
Next
t2# = Timer
Print Using "###.##### seconds with SteveSwap"; t2# - t1#
Sub SteveSwap (s1 As String, pos1 As Long, s2 As String, pos2 As Long, length As Long)
$Checking:Off
Static As _MEM m1, m2, m3
m1 = _Mem(_Offset(s1), Len(s1)): m2 = _Mem(_Offset(s2), Len(s2))
If m3.SIZE = 0 Then m3 = _MemNew(1000) 'note to make this large enough so it's always large enough to handle your strings
_MemCopy m1, m1.OFFSET + pos1 - 1, length To m3, m3.OFFSET
_MemCopy m2, m2.OFFSET + pos2 - 1, length To m1, m1.OFFSET + pos1 - 1
_MemCopy m3, m3.OFFSET, length To m2, m2.OFFSET + pos2 - 1
_MemFree m1
_MemFree m2
$Checking:On
End Sub
Now note that I engineered this a little different from what we had before. I figured, "Hey! Why the heck isn't this as versatile as possible for us?"
Well, NOW IT IS!!
Now we send it two strings (or one string referenced twice, if we so desire), and we sent it the positions we want swapped, *and* we send it the length we want swapped.
So in this case, my two strings are:
"ABCDEFGHIJ"
"1234567890"
And I tell it I want to swap the first string, second position with the second string, second position, for three characters. And that's what it does. The "BCD" changes places with the "234".
And it does this quickly... 10,000,000 times in 0.2 seconds on my laptop.
And how would this compare with the AscSwap?? AscSwap takes 0.05 seconds, but that's *per character*. Since this is moving 3 characters, I would assume 0.15 seconds would be as good as it would be, and probably slower due to looping overhead.
But *this* can do any length of string with the swap.... and from initial testing, it doesn't drop in performance very much. 7 characters perform the same as 3 characters, so no real increase in time required. I haven't bothered to test it with some long strings to see how much of a hit it would take with a few hundred characters being swapped from one string to another, as I just don't think I'd ever have any use for such large swaps like this.
And *YES*, you can swap the same string, if you desire. Nothing to prevent you from doing so, if you want.
Now, with all the highlights mentioned, let me add some nice "WOAH THERE SON!!" warnings.
Since this is supposed to be nice and quick, with speed and performance as its key note, I added *ZERO* error checking here. In fact, I turned $CHECKING:OFF completely. So you, as the end user, would have to make certain that the parameters you pass are within bounds, and that you're not overlapping segments. You start passing it values that don't work, it *will blow up on you*. Your computer will melt and turn into swiss cheese and when you come crying over it, I'll just laugh and say... "Well... did you read my whole post and the warning at the end of it?"
So... don't send this bad strings, bad parameters, and such things.
And... It could *still* end up returning you false data at some point. Chances are it won't, but it *COULD*. This works with the unsafe _MEM method with variable length strings. Variable length strings *can* move in memory at any time. The actual chance however of this moving inside such a small loop, is reasonably small and inconsequential to me. I don't see why doing this type of action would trigger any sort of memory movement or whatnot, but if one were to have something on an ON TIMER event, or perhaps even a background process kick in suddenly, the strings *could* move after we took a look at where they were in memory, and then we'd be swapping data with random junk.
I don't personally *think* it's likely to happen, and I'd toss it into one of my personal programs under the assumption that it'd be safe to do so, but then again I'm not coding nuclear launch codes for the space shuttle or anything. Just be aware of the possible glitch, in case it does happen at some point for you.
Posts: 2,910
Threads: 305
Joined: Apr 2022
Reputation:
167
Just for fun, and maybe someone else already did this (I'm late tot the party)...
Code: (Select All)
Dim Shared t$
t$ = "Pete's Tremendous. Steve's Amazing.": Print t$
swapx Mid$(t$, 8, 10), Mid$(t$, 28, 7)
Print t$
Print
t$ = "My apple is green. Your tomatoe is red.": Print t$
swapx Mid$(t$, 4, 5), Mid$(t$, 25, 7)
Print t$
Sub swapx (b$, a$)
i = Len(t$) - (InStr(t$, a$) - 1 + Len(a$))
j = InStr(t$, b$) - 1
k = j + Len(b$) + 1
temp1$ = Mid$(t$, 1, j) + a$
temp2$ = Mid$(Mid$(t$, k), 1, Len(Mid$(t$, k)) - Len(a$) - i) + b$
t$ = temp1$ + temp2$ + Mid$(t$, Len(temp1$) + Len(temp2$) + 1)
End Sub
Like I said, just for fun, because it isn't bullet proof. Since it uses INSTR() we can thuck fings up by working with sentences that have replacement parts repeated in the sentence. In other words, INSTR() would always pick the first occurrence, even if that's not the one your wanted swapped in the sentence.
Now if you were okay with not making the sub-strings, as you called them, hard coded, you could DIM shared the variables used to determine those sub-strings and write the algorithm differently. Like I said, this was fun, because I decided to see if I could come up with anything using those hard coded values, and I sorta did.
Pete
Oh, and swap that first sentence back before Steve and I sue your ASCII!
Posts: 956
Threads: 52
Joined: May 2022
Reputation:
38
I think the old Basic fighters are really getting old!
Code: (Select All)
'ABCDEFGHIJ und 1234567890 tauschen die Plaetze: BCD und 234
'26. Dez. 2026
Option _Explicit
Dim As String strBuchstaben, strZahlen, strTeilbuchstaben, strTeilzahlen
Dim As String strNeuBuchstaben, strNeuZahlen
strBuchstaben = "ABCDEFGHIJ"
strZahlen = "1234567890"
Print strBuchstaben
Print strZahlen
Print
strTeilbuchstaben = Mid$(strBuchstaben, 2, 3)
Print strTeilbuchstaben
strTeilzahlen = Mid$(strZahlen, 2, 3)
Print strTeilzahlen
Print
strNeuBuchstaben = Left$(strBuchstaben, 1) + strTeilzahlen + Mid$(strBuchstaben, 5)
Print strNeuBuchstaben
Print
strNeuZahlen = Left$(strZahlen, 1) + strTeilbuchstaben + Mid$(strZahlen, 5)
Print strNeuZahlen
End
Posts: 3,446
Threads: 376
Joined: Apr 2022
Reputation:
345
(12-26-2025, 10:42 PM)Kernelpanic Wrote: I think the old Basic fighters are really getting old! 
Code: (Select All)
'ABCDEFGHIJ und 1234567890 tauschen die Plaetze: BCD und 234
'26. Dez. 2026
Option _Explicit
Dim As String strBuchstaben, strZahlen, strTeilbuchstaben, strTeilzahlen
Dim As String strNeuBuchstaben, strNeuZahlen
strBuchstaben = "ABCDEFGHIJ"
strZahlen = "1234567890"
Print strBuchstaben
Print strZahlen
Print
strTeilbuchstaben = Mid$(strBuchstaben, 2, 3)
Print strTeilbuchstaben
strTeilzahlen = Mid$(strZahlen, 2, 3)
Print strTeilzahlen
Print
strNeuBuchstaben = Left$(strBuchstaben, 1) + strTeilzahlen + Mid$(strBuchstaben, 5)
Print strNeuBuchstaben
Print
strNeuZahlen = Left$(strZahlen, 1) + strTeilbuchstaben + Mid$(strZahlen, 5)
Print strNeuZahlen
End
![[Image: Old-Basic-Kaempfer2025-12-26-234033.jpg]](https://i.ibb.co/fdMrqWQ8/Old-Basic-Kaempfer2025-12-26-234033.jpg)
@Kernalpanic Sure, that works, but it works *slow*. Run it a few thousand times and see how long it takes to separate strings and then add them back together like that. I was showing you a nice fast way to do this (with a few careful limitations). Using strings like this is simply inherently sloooow due to the internals and use of temp strings and string clean up and sting copying and all sorts of stuff like that going on behind the scene.
Posts: 956
Threads: 52
Joined: May 2022
Reputation:
38
Quote:@Kernalpanic Sure, that works, but it works *slow*. Run it a few thousand times and see how long it takes to separate strings and then add them back together like that. I was showing you a nice fast way to do this (with a few careful limitations). Using strings like this is simply inherently sloooow due to the internals and use of temp strings and string clean up and sting copying and all sorts of stuff like that going on behind the scene.
Yes, if there are more changes than one need two files, I think so and have to put them in a loop. The crucial question, however, is whether the same positions should always be swapped between the two files. For example:
1st file: Letters
2nd file: Numbers
The positions 2, 3, 4 in the letters should always be swapped with positions 6, 7, 8 in the numbers. Only then does a loop make sense. Is there using _Mem$ faster than using instructions from QB? When using _Mem$, one have to write to memory and then read it back.
But if the positions to be swapped alternate between letters and numbers, then the user has to intervene, and then one can forget about the time. - Or one need a third file from which the changing positions can be read. It's all very complicated.
|