给定一个包含四个 8 位无符号整数的数组,例如 32 位 RGBA 颜色
rgba = [255, 255, 255, 255] # white
将这四个 Fixnum 组合成一个 32 位整数的最有效方法是什么?
目前,我正在使用打包和解包:
rgba.pack('C*').unpack('L')[0] #=> 4294967295
# Check work: same value as corresponding hex literal
0xffffffff #=> 4294967295
但我想知道是否有更有效的方法。 我发现了这个C++问题:
将两条短裤组合成 int 的最干净方式
我认为<<
是一个"转变",|
是一个"面具",但我对这些运算符的了解不够,也从未在 ruby 中使用过它们。
将每个元素移动 24 - (索引 * 8),然后将它们全部移在一起:
rgba = [255, 255, 255, 255]
rgba[0] << 24 | rgba[1] << 16 | rgba[2] << 8 | rgba[3]
我没有移位rgba[3]
因为移位零没有效果。
一些测量:
使用unpack
Benchmark.measure do
100_000.times do
rgba = [255, 255, 255, 255]
rgba.pack('C*').unpack('L')[0]
end
end
结果:
=> #<Benchmark::Tms:0x007fe137005350
@cstime=0.0,
@cutime=0.0,
@label="",
@real=0.146899,
@stime=0.0,
@total=0.1399999999999999,
@utime=0.1399999999999999>
使用按位运算符
Benchmark.measure do
100_100.times do
rgba = [255, 255, 255, 255]
rgba[0] << 24 | rgba[1] << 16 | rgba[2] << 8 | rgba[3]
end
end
结果:
=> #<Benchmark::Tms:0x007fd66438fd28
@cstime=0.0,
@cutime=0.0,
@label="",
@real=0.088995,
@stime=0.0,
@total=0.08000000000000007,
@utime=0.08000000000000007>