On Mon, May 12, 2003 at 08:31:58AM +0900, Ryan Pavlik wrote:
> On Mon, 12 May 2003 06:56:27 +0900
> "meinrad.recheis" <my.name.here / gmx.at> wrote:
> 
> <snip> 
> > data = ''
> > (width*height).times{
> >   data += rgb.read( 3) + alpha.read( 1)
> > }

 += strikes as extremely inefficient, as it is creating new increasingly big String
objects on each iteration!! Ruby will spend quite some time just
duplicating the string (ie copying data) and then GC'ing, in fact that'd
be O(N^2). Although nearly as bad (making heavy use of realloc), using
#<< should give a significant speedup, and you cannot get it much easier
than s/+=/<</ ;-)


See:

batsman@tux-chan:/tmp$ cat ae.rb

rgb = File.new "rgbfile", 'rb'

alpha = File.new "alphafile", 'rb'

width = height = ARGV[0].to_i

data = ''
(width*height).times{
        data << rgb.read(3) + alpha.read( 1)
}
p data.size

batsman@tux-chan:/tmp$ cat ae1.rb

rgb = File.new "rgbfile", 'rb'

alpha = File.new "alphafile", 'rb'

width = height = ARGV[0].to_i

data = ''
(width*height).times{
        data += rgb.read(3) + alpha.read( 1)
}
p data.size


batsman@tux-chan:/tmp$ time ruby ae.rb 100
40000

real    0m0.071s
user    0m0.070s
sys     0m0.000s
batsman@tux-chan:/tmp$ time ruby ae.rb 200
160000

real    0m0.483s
user    0m0.460s
sys     0m0.010s
batsman@tux-chan:/tmp$ time ruby ae.rb 300
360000

real    0m2.067s
user    0m2.060s
sys     0m0.010s
batsman@tux-chan:/tmp$ time ruby ae1.rb 100
40000

real    0m0.555s
user    0m0.530s
sys     0m0.020s
batsman@tux-chan:/tmp$ time ruby ae1.rb 200
160000

real    0m9.316s
user    0m8.420s
sys     0m0.730s
batsman@tux-chan:/tmp$ time ruby ae1.rb 300
360000

real    1m3.309s
user    0m51.880s
sys     0m10.480s


You can see that ae.rb's execution time still grows faster than
linearly... A better solution is 

batsman@tux-chan:/tmp$ cat ae2.rb

rgb = File.new "rgbfile", 'rb'

alpha = File.new "alphafile", 'rb'

width = height = ARGV[0].to_i
data = String.new(" " * 4*width*height)
# this sucks, would like to create a String w/ a given capa,
# IRC that was considered for/possible in 1.8, but not sure

(width*height).times{ |idx|
        data[idx*4, 4] = rgb.read(3) + alpha.read( 1)
}

p data.size

Now:

batsman@tux-chan:/tmp$ time ruby ae2.rb 100
40000

real    0m0.053s
user    0m0.050s
sys     0m0.000s
batsman@tux-chan:/tmp$ time ruby ae2.rb 200
160000

real    0m0.186s
user    0m0.170s
sys     0m0.010s
batsman@tux-chan:/tmp$ time ruby ae2.rb 300
360000

real    0m0.391s
user    0m0.370s
sys     0m0.010s

batsman@tux-chan:/tmp$ ruby -v
ruby 1.6.8 (2003-02-28) [i386-linux]

Not bad, a >150-fold speedup from your original script :-)

You might consider using Inline for this stuff, that'd be pretty neat.

-- 
 _           _                             
| |__   __ _| |_ ___ _ __ ___   __ _ _ __  
| '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ 
| |_) | (_| | |_\__ \ | | | | | (_| | | | |
|_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_|
	Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

I did this 'cause Linux gives me a woody.  It doesn't generate revenue.
	-- Dave '-ddt->` Taylor, announcing DOOM for Linux