Fastest algorithm to print all 16 bit binary numbers in Powershell?

PowerShell should print all 16-bit binary numbers with leading zeros, such as:

0000000000000000
0000000000000001
0000000000000010
0000000000000011
...
1111111111111100
1111111111111101
1111111111111110
1111111111111111

      

My current code looks like this:

0 .. 65535 | % { "{0:D16}" -f [int64][convert]::ToString($_,2) }

      

But I am wondering if there are other algorithms that would complete the task faster.

+3


source to share


1 answer


tl; dr The following approach, using caching and array lookup, is faster, but may not be possible due to other bottlenecks.

Here's a version using caching. However, Measure-Command

there is no significant improvement (3.5 vs. 3.8 seconds elapsed) - I expected to see a much larger difference.

$l = @(0) * 256

0..255 | % {
    $l[$_] = "{0:D8}" -f [int64][convert]::ToString($_,2)
}

0 .. 65535 | % {
    $l[$_ / 256 ] + $l[$_ -band 255]   # no -shr in PS before 3.0
}

      


There are two "slow" parts to this problem. One is that the use is %{}

slower compared to a simple loop. Using the above modified to the next (which is not very useful) exits in 0.3 seconds.

For ($i = 0; $i -lt 65535; $i = $i + 1) {
    $line = $l[$i / 256 ] + $l[$i -band 255]
}

      



Whereas a similarly modified and equally useless version of the original completes in 0.5 seconds. This is slightly slower than the proposed cache version, although the proposed approach does not ultimately impact the bottleneck or wall clock.

For ($i = 0; $i -lt 65535; $i = $i + 1) {
    $line = "{0:D16}" -f [int64][convert]::ToString($i,2)
}

      

Using manual data collection with a given array is also much faster than %{}

and for my version it runs in 0.5 seconds - it will be slightly slower for the original approach, say 0.8 seconds.

$r = @("") * 65536
# ..
For ($i = 0; $i -lt 65535; $i = $i + 1) {
    $r[$i] = $l[$i / 256 ] + $l[$i -band 255]
}

      

Second, actually materializing with help is Write-Output

very slow and slower than collecting results with %{}

. Using Write-Output

or Write | Output-File ..

results in times longer than 8 seconds.

$r = @("") * 65536
$l = @(0) * 256

For ($i = 0; $i -lt 256; $i = $i + 1) {
    $l[$i] = "{0:D8}" -f [int64][convert]::ToString($i, 2)
}

For ($i = 0; $i -lt 65535; $i = $i + 1) {
    $r[$i] = $l[$i / 256 ] + $l[$i -band 255]
}

# to here in about 0.5 seconds
Write $r | Out-File results.txt

# almost another 8 seconds to get here

      

+4


source







All Articles