Memoize (reposting via ML)


#1

(Reposting via ML as gateway apparently didn’t send this through.)

I was trying to use memoize the other day (v 1.2 from Dan B. –
is there a different/better one?). Ran into some problems…

In this dumb example, where I’m passing the same parameter every time,
the speed should blaze, should it not?

This doesn’t work for me. I see no measurable speed difference in these
three cases. What am I doing wrong?

Thanks,
Hal

require ‘memoize’

include Memoize

def zeta(x)
r2d = 360.0/(2.0Math::PI) # Radians to degrees
2.0
(Math.sin(x/r2d))*(Math.cos(x/r2d))
end

puts Time.now
1000000.times { z = zeta(2.0) }
puts Time.now

memoize(:zeta)

puts Time.now
1000000.times { z = zeta(2.0) }
puts Time.now

memoize(:zeta,“z.cache”)

puts Time.now
1000000.times { z = zeta(2.0) }
puts Time.now


#2

On Wed, 2006-02-01 at 10:22 +0900, Hal F. wrote:

This doesn’t work for me. I see no measurable speed difference in these
three cases. What am I doing wrong?

It may be that (relative to the overhead of method calls, etc), the
calculation is less expensive than you suppose.

-mental


#3

MenTaLguY wrote:

On Wed, 2006-02-01 at 10:22 +0900, Hal F. wrote:

This doesn’t work for me. I see no measurable speed difference in these
three cases. What am I doing wrong?

It may be that (relative to the overhead of method calls, etc), the
calculation is less expensive than you suppose.

C’est possible… but with the silly hash-based implementation in
TRW1, I saw a significant speedup of this same function. And
memoize is not so complicated…

James Edward G., are you listening? Don’t you have a memoize of
your own? What does it do with this function?

Cheers,
Hal


#4

I added a “sleep 1” line to zeta to exaggerate the time of an uncached
method call.

It is working.

–Brian B.

def zeta(x)
sleep 1
r2d = 360.0/(2.0Math::PI) # Radians to degrees
2.0
(Math.sin(x/r2d))*(Math.cos(x/r2d))
end

t1 = Time.now
10.times { z = zeta(2.0) }
t2 = Time.now

memoize(:zeta)

t3 = Time.now
10.times { z = zeta(2.0) }
t4 = Time.now

memoize(:zeta,“z.cache”)
t5 = Time.now
10.times { z = zeta(2.0) }
t6 = Time.now

puts “#{t2 - t1}, #{t4 - t3}, #{t6 - t5}” # => 10.0, 1.0, 0.0


#5

On Jan 31, 2006, at 8:07 PM, Hal F. wrote:

James Edward G., are you listening?

Yes, I am.

Don’t you have a memoize of your own?

It’s just a toy, but yes. I didn’t bother packaging it up though,
since there didn’t seem to be interest in it. I’ll attach the
library to this message, in case you want to fiddle with it.

What does it do with this function?

Mine is maybe slightly faster, but it’s really the same story.
Running with memoize.rb I see:

$ ruby hals_memoize.rb
Unmemoized:
4.436923 seconds.
Memoized:
5.266704 seconds.
Memoized (file):
5.324959 seconds.

My library shows:

$ ruby hals_memoize.rb
Unmemoized:
4.47798 seconds.
Memoized:
3.883453 seconds.

I have to agree with the others. The operations are just too fast.
You’ve got to get some processing or recursion in there to see a big
boost. Anything you can run 1,000,000 tests on without memoization
just isn’t stressful enough to benefit from it much.

Anyway, here’s the test I ran with my code:

require ‘memoizable’

extend Memoizable

def zeta(x)
r2d = 360.0/(2.0Math::PI) # Radians to degrees
2.0
(Math.sin(x/r2d))*(Math.cos(x/r2d))
end

puts “Unmemoized:”
start = Time.now
1000000.times { z = zeta(2.0) }
puts “#{Time.now - start} seconds.”

memoize(:zeta)

puts “Memoized:”
start = Time.now
1000000.times { z = zeta(2.0) }
puts “#{Time.now - start} seconds.”

END

And again the library is attached.

Sorry I wasn’t more help.

James Edward G. II