最快的算法在Powershell中打印所有16位二进制数?

时间:2014-08-20 22:40:33

标签: algorithm powershell optimization binary

PowerShell应该打印所有带有前导零的16位二进制数,如下所示:

0000000000000000
0000000000000001
0000000000000010
0000000000000011
...
1111111111111100
1111111111111101
1111111111111110
1111111111111111

我目前的代码如下:

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

但我想知道是否有其他算法可以更快地执行任务。

1 个答案:

答案 0 :(得分:4)

tl; dr 以下使用缓存和数组查找的方法更快,但由于其他瓶颈可能无法实现。

这是一个使用缓存的版本。但是,根据Measure-Command,没有明显的改善(3.5秒vs3.8秒) - 我期待看到更大的差异。

$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
}

这个问题有两个“慢”部分。一个是使用%{} 与普通循环相比。使用以上修改后的(不是很有用)在0.3秒内完成。

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

虽然原版的类似修改版本同样无用,但在0.5秒内完成。即使提议的方法最终不会影响瓶颈或挂钟, 比缓存的建议版本慢一点。

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

使用预设数组手动收集输出也比%{}快得多,并且我的版本在0.5秒内运行 - 对于原始方法,它会运行一点慢,比如0.8秒。

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

其次,实际使用Write-Output实现非常慢并且比使用%{}收集结果要慢。使用Write-OutputWrite | Output-File ..会导致超过8秒的时间。

$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