# Storing values for later use

**URL:** <https://www.ruby-forum.com/t/storing-values-for-later-use/139835>\
**Category:** Ruby\
**Created:** [June 7, 2008, 10:56pm UTC](https://www.ruby-forum.com/t/storing-values-for-later-use/139835 "2008-06-07T22:56:05Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [June 7, 2008, 10:56pm UTC](https://www.ruby-forum.com/t/storing-values-for-later-use/139835/1 "2008-06-07T22:56:05Z")

</div>

I have a group of expensive (as in slow) c functions that take an  
arrays and  
parameters, process them and return one or more arrays to Ruby.

These functions can take a long time to process and in some cases are  
quite complex, so I really would like to keep them in c.

Example: My program calculates the first 1000 elements of a function.  
My c function can calculate all 1000 elements  
in about the same time as it take to calculate the 999’th element, so  
rather calling c over and over is way too slow!

This function can have 1 to 6 parameters that are unknown until run  
time  
so I can’t just “set them up” in advance.  
I was thinking about making a hash so I could do something like  
funcvals[(func\_name + parm1.to\_s + parm2.to\_s  
parm3.to\_s).intern].storedvalue  
but this is slow, ugly and messy!

Does anyone have a clever/fast idea how to do this best in Ruby?  
(I think this is the “opposite” of a lazy function. Is there a term  
for this  
so I can sound smarter next time?)

Thanks,  
Tom

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [June 7, 2008, 11:50pm UTC](https://www.ruby-forum.com/t/storing-values-for-later-use/139835/2 "2008-06-07T23:50:41Z")

</div>

On Saturday 07 June 2008 15:53:49 removed\_email\_address@domain.invalid wrote:

> Example: My program calculates the first 1000 elements of a function.  
> My c function can calculate all 1000 elements  
> in about the same time as it take to calculate the 999’th element, so  
> rather calling c over and over is way too slow!
> 
> This function can have 1 to 6 parameters that are unknown until run  
> time  
> so I can’t just “set them up” in advance.

Depends what you mean by “in advance”.

Sounds like you had the right idea with the hash, but probably better to  
wrap  
it in some sort of object. For example:

class BigCStuff  
…  
def function\_I\_want\_to\_put\_off \*args  
@argument\_lists \<\< args  
end  
…  
def [] i  
self.result\_array[i]  
end  
def result\_array  
@result\_array ||= actual\_C\_call(@argument\_lists)  
end  
end

I’m trying not to make too many assumptions about what you’re doing  
here…

> (I think this is the “opposite” of a lazy function.

By the way, what I’ve done above is actually a lazy object of sorts.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [June 7, 2008, 11:07pm UTC](https://www.ruby-forum.com/t/storing-values-for-later-use/139835/3 "2008-06-07T23:07:49Z")

</div>

-------- Original-Nachricht --------

> Datum: Sun, 8 Jun 2008 05:53:49 +0900  
> Von: removed\_email\_address@domain.invalid  
> An: removed\_email\_address@domain.invalid  
> Betreff: storing values for later use

> rather calling c over and over is way too slow!  
> (I think this is the “opposite” of a lazy function. Is there a term  
> for this  
> so I can sound smarter next time?)
> 
> Thanks,  
> Tom

Tom,

not quite sure whether I understood what you’re after, but it might be  
Marshalling:

[http://www.ruby-doc.org/core/classes/Marshal.html](http://www.ruby-doc.org/core/classes/Marshal.html)

Best regards,

Axel

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [June 8, 2008, 12:09am UTC](https://www.ruby-forum.com/t/storing-values-for-later-use/139835/4 "2008-06-08T00:09:26Z")

</div>

Thanks for the quick reply.

I have no desire to store values except in the class while my program  
is running.

f(a,b,c) returns a 1000 elemeent array. I want to call the function  
with a=1,b=2 and c = -3). It takes ten seconds for it to call the c  
function and fill the array.

I later call the same functions with different values of a,b and c.

Then I decide I want the values of the function with a=1, b=2 and c =  
-3 again. I want  
to avoid calling C again and recalculating the numbers I already have  
calculated.

example: (sorry if this is not “quite” ruby, I am still learning!)  
funcname = “thiscfunction”  
x = myclass.callc(funcname,1,2,3)[55]  
#first call, get all values for a=1,b=2,c=3 and return the  
55’th  
y = myclass.callc(funcname,3,2,1)[1] # new args, so C has to be  
called again  
z = myclass.callc(funcname,1,2,3)[11]  
# second call with 1,2,3, don’t call C again just lookup and the  
11’th value

The program has many function and argument combinations (they are  
defined at runtime)  
but chances are I will reuse them many times withing the program, so  
this litterally could make my program thousands of times faster.

Sorry if i did a poor job in explaining this.

Thanks,  
Tom  
Tom

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [June 8, 2008, 12:00am UTC](https://www.ruby-forum.com/t/storing-values-for-later-use/139835/5 "2008-06-08T00:00:37Z")

</div>

On 07.06.2008 22:52, removed\_email\_address@domain.invalid wrote:

> rather calling c over and over is way too slow!
> 
> This function can have 1 to 6 parameters that are unknown until run  
> time  
> so I can’t just “set them up” in advance.  
> I was thinking about making a hash so I could do something like  
> funcvals[(func\_name + parm1.to\_s + parm2.to\_s  
> parm3.to\_s).intern].storedvalue  
> but this is slow, ugly and messy!

I’d say you’d better use an array as Hash key.

> Does anyone have a clever/fast idea how to do this best in Ruby?  
> (I think this is the “opposite” of a lazy function. Is there a term  
> for this  
> so I can sound smarter next time?)

Sounds like memoize would fit.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [June 11, 2008, 4:50am UTC](https://www.ruby-forum.com/t/storing-values-for-later-use/139835/6 "2008-06-11T04:50:36Z")

</div>

Hey Tom,

The previous responders were right on. Memoization is the concept of  
caching the results of a function call. Googling ‘ruby memoization’  
will yield far better descriptions than mine, but here’s a simple  
example using the ruby gem Memoize. When it is mixed-in to a class  
definition, it adds the method memoize() to instances of the class.  
When you want to begin storing results of a calculation, call memoize  
on the object with the symbol name (the colon string) of the method  
you’d like to begin caching.

require ‘memoize’

class CalcLibrary  
include Memoize  
def call\_c(function\_name, \*args\_array)  
# This method calls into the C extension (I assume)  
# And returns an array (we’ll just return randoms)  
return\_array = []  
srand Time.now.usec  
return\_array \<\< rand(10000)  
return\_array \<\< rand(10000)  
end  
end

# A quick test

puts “-- No memoize() call yet --”  
clib = CalcLibrary.new

puts “Result one:”  
puts clib.call\_c(“rand”)[1]  
puts “Result two:”  
puts clib.call\_c(“rand”)[1]  
puts “Result three:”  
puts clib.call\_c(“rand”, 2)[1]

puts “-- Memoized --”  
clib.memoize :call\_c

puts “Result one:”  
puts clib.call\_c(“rand”)[1]  
puts “Result two:” # Should be the same as result 1 if  
cached  
puts clib.call\_c(“rand”)[1]  
puts “Result three:”  
puts clib.call\_c(“rand”, 2)[1]

The Memoize module also includes the ability to store and load caches  
out to a file, but it’s easy to get into trouble that way without  
diving into how it’s working under-the-hood. Good luck with your  
project!
