给定一个包含四个8位无符号整数的数组,例如32-bit RGBA color
rgba = [255, 255, 255, 255] # white
将这四个Fixnums合并为一个32位Integer的最有效方法是什么?
目前,我正在使用pack and unpack:
rgba.pack('C*').unpack('L')[0] #=> 4294967295
# Check work: same value as corresponding hex literal
0xffffffff #=> 4294967295
但我想知道是否有更有效的方法。我发现了这个C ++问题:
Cleanest way to combine two shorts to an int
我认为<<
是一个&#34;转移&#34;而|
是一个&#34;掩码&#34;,但我对这些运营商了解不多,而且从未在红宝石中使用它们。
答案 0 :(得分:2)
将每个元素移动 24 - (index * 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>