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.
source to share
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
source to share