vxs*_*122 4 algorithm binary powershell optimization
PowerShell 应该打印所有带有前导零的 16 位二进制数,如下所示:
0000000000000000
0000000000000001
0000000000000010
0000000000000011
...
1111111111111100
1111111111111101
1111111111111110
1111111111111111
Run Code Online (Sandbox Code Playgroud)
我当前的代码如下所示:
0 .. 65535 | % { "{0:D16}" -f [int64][convert]::ToString($_,2) }
Run Code Online (Sandbox Code Playgroud)
但我想知道是否还有其他算法可以更快地执行任务。
tl;dr以下使用缓存和数组查找的方法更快,但由于其他瓶颈可能无法实现。
这是一个使用缓存的版本。但是,按照标准Measure-Command没有显着改善(3.5 秒对 3.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
}
Run Code Online (Sandbox Code Playgroud)
这个问题有两个“慢”部分。一种是利用%{}正在缓慢相比普通的循环。使用上述修改为以下(这不是很有用)在 0.3 秒内完成。
For ($i = 0; $i -lt 65535; $i = $i + 1) {
$line = $l[$i / 256 ] + $l[$i -band 255]
}
Run Code Online (Sandbox Code Playgroud)
虽然经过类似修改但同样无用的原始版本在 0.5 秒内完成。这是一个好一点比缓存建议的版本慢,即使该方法不会最终影响到瓶颈或挂钟。
For ($i = 0; $i -lt 65535; $i = $i + 1) {
$line = "{0:D16}" -f [int64][convert]::ToString($i,2)
}
Run Code Online (Sandbox Code Playgroud)
使用预先设置的数组手动收集输出也比%{}我的版本快得多,它在 0.5 秒内运行 - 对于原始方法,它的运行速度会慢一些,比如 0.8 秒。
$r = @("") * 65536
# ..
For ($i = 0; $i -lt 65535; $i = $i + 1) {
$r[$i] = $l[$i / 256 ] + $l[$i -band 255]
}
Run Code Online (Sandbox Code Playgroud)
其次,实际上物化Write-Output是很慢的,比收集与结果更慢%{}。使用Write-Output或Write | Output-File ..导致时间超过 8 秒。
For ($i = 0; $i -lt 65535; $i = $i + 1) {
$line = "{0:D16}" -f [int64][convert]::ToString($i,2)
}
Run Code Online (Sandbox Code Playgroud)