Swapping Integers

There was a post yesterday on another subreddit (I can’t remember which and can’t find the post now) in which I saw something kind of neat in another programming language that I wanted to see if it was possible in PowerShell.

So here is the problem: You have 2 integer variables and you want to swap them. Let’s say they are [int]$A and [int]$B. What you want to to is swap it so the final value of $A is the initial value of $B and the final value of $B is the initial value of $A. This can be very easily done by introducing [int]$C to temporarily store the value of either $A or $B so it can be assigned back. Like this:

[int]$A = 10 [int]$B = 20 [int]$C = $A $A = $B $B = $C "A is $A" "B is $B" A is 20 B is 10 

Lets say you live in a fictional world where you are somehow running PowerShell but don’t have the spare memory to allocate a 3rd [int]. Can you swap the 2 values without the third? You can!!

[int]$A = 10 [int]$B = 20 $A = $A -bxor $B $B = $A -bxor $B $A = $A -bxor $B "A is $A" "B is $B" A is 20 B is 10 

Go ahead and run that for yourself and see.

SO what is this witchcraft? It’s called an XOR Swap. It’s not a new concept, but I thought it was pretty clever and I just wanted to see if PowerShell could also do it. There are a multitude of reason why you shouldn’t do this, including others not knowing what is going on with the code. PowerShell almost never operates in a memory starved environment where it needs to by hyper-conscious of RAM consumption. Also it performs slower (see the tests below).

Now, how should you REALLY swap variables in PowerShell? We are in luck! We don’t need to create a $C either. Instead we can take advantage of the builtin ability to do multiple assignments:

[int]$A = 10 [int]$B = 20 $A,$B = $B,$A "A is $A" "B is $B" A is 20 B is 10 

Well, that’s how you are supposed to do it properly, anyway, but which way is faster??

$xor = 1..1000 | ForEach-Object{ Measure-Command{ [int]$A = 10 [int]$B = 20 $A = $A -bxor $B $B = $A -bxor $B $A = $A -bxor $B } } $abc = 1..1000 | ForEach-Object{ Measure-Command{ [int]$A = 10 [int]$B = 20 [int]$C = $A $A = $B $B = $C } } $multiassign = 1..1000 | ForEach-Object{ Measure-Command{ [int]$A = 10 [int]$B = 20 $A,$B = $B,$A } } "XOR Swap (ms):" $xor.TotalMilliseconds | Measure-Object -Average -Maximum -Minimum -Sum "ABC Swap (ms):" $ABC.TotalMilliseconds | Measure-Object -Average -Maximum -Minimum -Sum "Mutliple Assingmnet Swap (ms):" $multiassign.TotalMilliseconds | Measure-Object -Average -Maximum -Minimum -Sum XOR Swap (ms): Count : 1000 Average : 0.0192963 Sum : 19.2963 Maximum : 2.9215 Minimum : 0.013 Property : ABC Swap (ms): Count : 1000 Average : 0.0190289 Sum : 19.0289 Maximum : 3.3913 Minimum : 0.0121 Property : Mutliple Assingmnet Swap (ms): Count : 1000 Average : 0.0134132 Sum : 13.4132 Maximum : 0.2463 Minimum : 0.0108 Property : 

The Multiple assignment method wins on average, minimum, and maximum over 1000 iterations.

Anyway, I just felt like sharing.

submitted by /u/markekraus
[link] [comments]

Leave a Reply