Here is the fastest Ruby code I have been able to develop so far.
Note the use of the Hash caused the Ruby code to run 14% slower than
when the Hash was not used.
Also it is worth noting that I was able to whip-up some Python code
that runs this same problem in 2.278 secs using Python 2.5.1 and this
makes Python almost 30x faster than Ruby for this problem.
$h = Hash.new
(0..127).select {|x| $h[x.chr] = ((x & 0x7f) | 0x80).chr}
def scramble(fname)
f = File.new(fname, "rb")
_fname = fname + ".scrambled"
begin
File.exist?(_fname) if File.delete(_fname)
rescue
end
ff = File.new(_fname, "wb+")
for l in f
l.each_byte{|c| ff.write((c | 0x80).chr) }
end
f.close()
ff.close()
end
def _scramble(fname)
f = File.new(fname, "rb")
_fname = fname + ".scrambled"
begin
File.exist?(_fname) if File.delete(_fname)
rescue
end
ff = File.new(_fname, "wb+")
for l in f
l.each_byte{|c| ff.write($h[c]) }
end
f.close()
ff.close()
end
The slowest section of code is iteration of each_byte where Ruby
spends 50% of its time. Python spends 67% of its time translating
characters.
Also the Python community was very quick to help me out given the same
amount of time with this problem.
After this exorcise I can easily see why Ruby is relegated to the
kinds of problems people are willing to use Ruby for versus the far
more intense set of problem domains in which Python can be more easily
used.
Don't take me wrong, I neither love nor hate any languages I encounter
- I simply perform benchmarks and choose the fastest of the breed and
then I tend to use whichever languages or tools perform better. I find
it easier to meet customer expectations when I begin with a set of
tools that already runs reasonably fast. For some this means Ruby
runs reasonably fast however for me this means Ruby comes in dead-last
and therefore may not be worth using versus other languages or tools
that benchmark faster than Ruby does.
On the other hand, I am also waiting for Ruby 1.9.0 and YARV to see if
Ruby can be made to perform better than Ruby 1.8.6. Having said this
Ruby 1.9.0 has been in the works for about 18 months by now with no
real date other than Nov 2007 but Ruby 1.9.0 was supposed to be
release sometime during 2006 also. Sadly for me, or happily depending
on where you stand on this issue - even if Ruby were made to run
faster than Python but it lacked a byte-code compiler so I don't have
to ship source code I would still spend my time coding Python along
with the D Language just so I don't have to ship source code.
Ruby is ideal for those who don't care about performance or for Open
Source Projects where source code will be shipped - all other uses
Python will be faster.
···
On Sep 20, 7:16 pm, John Joyce <dangerwillrobinsondan...@gmail.com> wrote:
On Sep 20, 2007, at 8:50 PM, Brian Adkins wrote:
> On Sep 20, 6:02 pm, Ruby Maniac <raych...@hotmail.com> wrote:
>> I am new to Ruby and I could use some expert advice as to how I can
>> make this code run faster.
> Write a C extension. Seriously, Ruby is pretty darn slow at iterating
> over each byte of a file. The I/O is reasonable, but the byte
> iteration is terrible. You might get a small speedup by using
> File#read instead of File#each_byte:
> while (buffer = f.read(BUF_SIZE))
> buffer.each_byte {|b| ... }
> end
> I got about a 5% speedup using an 8K buffer.
> You also may want to consider the idiom:
> File.open(filename) do |f|
> ...
> end
> This will automatically close the file at the end of the block.
>> def scramble(fname)
>> f = File.new(fname, "rb")
>> _fname = fname + ".scrambled"
>> begin
>> File.exist?(_fname) if File.delete(_fname)
> You may want to double check the previous line.
>> rescue
>> end
>> ff = File.new(_fname, "wb+")
>> for l in f
>> l.each_byte{|c| ff.write((c | 0x80).chr) }
> So you don't need to get the original file data back, right? If you
> do, you may want to use xor instead, and if you don't, then why not
> just write zeros?
>> end
>> f.close()
>> ff.close()
>> end
Benchmark it so you can find the bottlenecks.- Hide quoted text -
- Show quoted text -