PowerShell应该打印所有带有前导零的16位二进制数,如下所示:
0000000000000000
0000000000000001
0000000000000010
0000000000000011
...
1111111111111100
1111111111111101
1111111111111110
1111111111111111
我目前的代码如下:
0 .. 65535 | % { "{0:D16}" -f [int64][convert]::ToString($_,2) }
但我想知道是否有其他算法可以更快地执行任务。
答案 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-Output
或Write | 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