For those that like a nice _MEM version of this, let me introduce the following little code snippet for you guys:
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.
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.


