Need for speed - array operations

Hi,

Im working on a library to decode medical image files, and some of these
files are encoded as ‘PALETTE COLOR’, which means you have a lookup
table for red, green and blue pixel values. The final RGB pixel array is
constructed by hitting the lookup table with the original pixel values.
In my implementation I am using an iterator, and it is kinda slow. I
cant spot an obvious way to improve on it though, so I thought I’d put
the question out here and see if any of you more experienced Rubyists
can suggest a more efficient way of doing this.

Thanks,
Chris

Example code:

Set up example arrays to test the algorithm:

lookup_values = Array.new
lookup_values << Array.new(256, 0)
lookup_values << Array.new(256, 1)
lookup_values << Array.new(256, 2)
pixels = Array.new(258000, rand(256))
rgb = Array.new(pixels.length*3)

The PALETTE transformation algorithm:

pixels.each_index do |i|
rgb[i*3] = lookup_values[0][pixels[i]]
rgb[(i3)+1] = lookup_values[1][pixels[i]]
rgb[(i
3)+2] = lookup_values[2][pixels[i]]
end

On 04/29/2011 10:54 AM, Chris L. wrote:

rgb = Array.new(pixels.length*3)

The PALETTE transformation algorithm:

pixels.each_index do |i|
rgb[i*3] = lookup_values[0][pixels[i]]
rgb[(i3)+1] = lookup_values[1][pixels[i]]
rgb[(i
3)+2] = lookup_values[2][pixels[i]]
end

You might try narray: http://narray.rubyforge.org/. It’s available as a
gem.

ralf

On Fri, Apr 29, 2011 at 1:05 PM, Ralf M. [email protected]
wrote:

the question out here and see if any of you more experienced Rubyists
lookup_values<< Array.new(256, 2)
You might try narray: http://narray.rubyforge.org/. It’s available as a gem.
Not so fast. There is room for optimization even in this
implementation. We can shave off over 12% with a pure Ruby solution:

13:18:20 Temp$ ruby19 lv.rb
user system total real
old prep 0.000000 0.000000 0.000000 ( 0.000000)
old 1.812000 0.000000 1.812000 ( 1.806000)
new prep 0.000000 0.000000 0.000000 ( 0.001000)
new 1.016000 0.047000 1.063000 ( 1.060000)

https://gist.github.com/948178

Kind regards

robert

Robert,
I’ve implemented your tweaked solution and indeed it runs significantly
faster! In retrospect it looks so obvious, almost embarrasing!

Thanks a million, your effort is appreciated!

Ralf,
yes I am aware of NArray, and probably that will be the optimal
solution. At some stage I will probably use it, however, at least for
now, I want to avoid external dependencies and just go with a pure Ruby
solution.

Thanks,
Chris

I’m experience the loss of speed in NArrays. Did you guys tried benching
a simple access to an element in NArray?

My benches show dramatical slowdown comparing to a Ruby built-in Array.
I already filled an issue here:
https://github.com/masa16/narray/issues/8.

Just a bit of an update:
Turns out the each_with_index iterator is INSANELY slow on ruby1.8 on
large arrays, so I had to use each_index instead and pixels[i] instead
of pix.

Still a happy ending though!

Chris

On 05/17/2011 01:26 PM, Pirogov Eugene wrote:

I’m experience the loss of speed in NArrays. Did you guys tried benching
a simple access to an element in NArray?

My benches show dramatical slowdown comparing to a Ruby built-in Array.
I already filled an issue here:
https://github.com/masa16/narray/issues/8.

It’s too simple a benchmark to demonstrate the efficiency of narray.
What it’s measuring is access time from ruby. For the first two cases,
the number in the ruby array is a fixnum (shifted by one bit and or-ed
with 0x01) that can simply be returned with no modification, as a 32 or
64 bit VALUE (ruby’s basic data type). In the third case, the number is
stored as an 8 bit signed int, which has to be converted to VALUE by
sign extending, shifting, and or-ing.

As soon as you start measuring operations whose inputs and outputs are
both NArrays (especially large ones), you’ll see the speed…

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs