[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

An integer's life span?

Sam Kong

8/7/2006 9:36:00 PM

Hello!


Here's my code.

---------------------
class Integer
def prime?
return false if self < 2
return @is_prime if @prime_cached
@prime_cached = true
(2..(self ** 0.5)).each do |i|
return (@is_prime = false) if i.prime? and self % i == 0
end
@is_prime = true
end
end
---------------------

I want each integer to remember if it's a prime number or not.
As the calculation uses cache of smaller prime numbers, it runs fast.
But I'm not sure if the cache is preserved after GC runs (when nothing
refers to the integers).
If the cache is not preserved, it's no use.

My first idea was keeping the cache in a class variables like
@@prime_numbers and @@max_cached.
But I think it would be better if each object remembers its own state.

What do you think?

Sam

12 Answers

Eric Hodel

8/7/2006 9:53:00 PM

0

On Aug 7, 2006, at 2:40 PM, Sam Kong wrote:

> I want each integer to remember if it's a prime number or not.
> As the calculation uses cache of smaller prime numbers, it runs fast.
> But I'm not sure if the cache is preserved after GC runs (when nothing
> refers to the integers).
> If the cache is not preserved, it's no use.

IIRC an Integer's instance variables are eternal due to various
implementation details.

--
Eric Hodel - drbrain@segment7.net - http://blog.se...
This implementation is HODEL-HASH-9600 compliant

http://trackmap.rob...



Gregory Brown

8/7/2006 10:53:00 PM

0

On 8/7/06, Eric Hodel <drbrain@segment7.net> wrote:

> IIRC an Integer's instance variables are eternal due to various
> implementation details.

Specifically due to the fact that integers are immediate values in ruby.
(Thus, are never collected)

So, attr_accessor prime would probably due the trick.

Gregory Brown

8/7/2006 10:55:00 PM

0

On 8/7/06, Gregory Brown <gregory.t.brown@gmail.com> wrote:

> So, attr_accessor prime would probably due the trick.

err, typo there, and here is an example of what i mean.

bash-3.1$ irb
>> class Integer; attr_accessor :prime; end
=> nil
>> 1.prime = true
=> true
>> 2.prime = true
=> true
>> 3.prime = true
=> true
>> 5.prime = true
=> true
>> 7.prime = true
=> true
>> (1..7).select { |n| n.prime }
=> [1, 2, 3, 5, 7]

might want to add a prime? method too.

Sam Kong

8/7/2006 11:13:00 PM

0

Gregory Brown wrote:
> On 8/7/06, Eric Hodel <drbrain@segment7.net> wrote:
>
>> IIRC an Integer's instance variables are eternal due to various
>> implementation details.
>
> Specifically due to the fact that integers are immediate values in ruby.
> (Thus, are never collected)

Thank you for the answer.
This is good news for my purpose.
However, that creates another worry.

(1..100000).each {|i|...}

Now there are 100000 integers in the memory which won't die.
Is it okay?

Sam


--
Posted via http://www.ruby-....

Gregory Brown

8/7/2006 11:39:00 PM

0

On 8/7/06, Sam Kong <sam.s.kong@gmail.com> wrote:
> Gregory Brown wrote:
> > On 8/7/06, Eric Hodel <drbrain@segment7.net> wrote:
> >
> >> IIRC an Integer's instance variables are eternal due to various
> >> implementation details.
> >
> > Specifically due to the fact that integers are immediate values in ruby.
> > (Thus, are never collected)
>
> Thank you for the answer.
> This is good news for my purpose.
> However, that creates another worry.
>
> (1..100000).each {|i|...}

Looks like in this case, they are garbage collected?

at startup
bash-3.1$ pmap 7764 | grep "total"
total 4560K

after each
bash-3.1$ pmap 7764 | grep "total"
total 4560K

> Now there are 100000 integers in the memory which won't die.
> Is it okay?

but after adding an accessor for x, and setting it to true:
(1..100000).each { |i| i.x = true }

bash-3.1$ pmap 7764 | grep "total"
total 16308K

Big increase, but still not *that* bad.

Rick DeNatale

8/8/2006 12:09:00 AM

0

On 8/7/06, Sam Kong <sam.s.kong@gmail.com> wrote:
> Hello!
>
>
> Here's my code.
>
> ---------------------
> class Integer
> def prime?
> return false if self < 2
> return @is_prime if @prime_cached
> @prime_cached = true
> (2..(self ** 0.5)).each do |i|
> return (@is_prime = false) if i.prime? and self % i == 0
> end
> @is_prime = true
> end
> end
> ---------------------
>
> I want each integer to remember if it's a prime number or not.
> As the calculation uses cache of smaller prime numbers, it runs fast.
> But I'm not sure if the cache is preserved after GC runs (when nothing
> refers to the integers).
> If the cache is not preserved, it's no use.
>
> My first idea was keeping the cache in a class variables like
> @@prime_numbers and @@max_cached.
> But I think it would be better if each object remembers its own state.
>
> What do you think?

I'm pretty sure that your concern about GC is moot, but just as long
as you stay with in the range of Fixnums. Fixnums are 'immediate'
objects, and never get collected. I Bignums are another matter.

For Fixnums your code works as is. The @prime_cached iv is not needed
however, here's another way to do it:

class Integer
def prime?
return false if self < 2
return @is_prime unless @is_prime.nil?
(2..self**0.5).each do | i |
return (@is_prime = false) if i.prime? and self % i == 0
end
@is_prime = true
end
end

--
Rick DeNatale

IPMS/USA Region 12 Coordinator
http://ipmsr12.denh...

Visit the Project Mercury Wiki Site
http://www.mercuryspace...

Jeremy Henty

8/8/2006 12:17:00 AM

0

On 2006-08-07, Sam Kong <sam.s.kong@gmail.com> wrote:

> (1..100000).each {|i|...}
>
> Now there are 100000 integers in the memory which won't die.

No there aren't. Immediate values don't allocate anything in memory.
They aren't pointers (even though under the hood Ruby coerces them to
the same type as non-immediate values that *are* pointers). Immediate
values aren't garbage collected because there is *nothing* to garbage
collect. They don't point to anything. What is there to collect?

Think of C. Does "long i ; i = 0 ; i = 1 ; i = 2 ; i = 3" consume any
more memory than "long i ; i = 0"? No, because the only memory
allocated is for the long variable "i". The values 0, 1, 2, 3, are
just constants that are copied (one after the other) into that single
previously allocated space. Ruby's immediate values are just like C
longs (in fact, under the hood, they *are* just C longs). Creating
them doesn't consume memory, it just copies them into a pre-existing
chunk of memory that was already allocated by the Ruby interpreter.

If you create lots of *references* to immediate values, eg. by writing
" a = (1..100000).collect {|i| i } ", then that *will* consume memory.
But that memory isn't being used to create immediate values, it's
being used to store those values inside an object. Once that object
is no longer referenced the memory is available to be recycled by the
garbage collector. All memory allocation/deallocation is associated
with the non-immediate object that holds those references. The
immediate values themselves allocate no memory at all.

Regards,

Jeremy Henty

Eric Hodel

8/8/2006 12:36:00 AM

0

On Aug 7, 2006, at 5:20 PM, Jeremy Henty wrote:

> On 2006-08-07, Sam Kong <sam.s.kong@gmail.com> wrote:
>
>> (1..100000).each {|i|...}
>>
>> Now there are 100000 integers in the memory which won't die.
>
> No there aren't. Immediate values don't allocate anything in memory.
> [... an accurate description of class Fixnum's implementation]

Also, since a Fixnum is immediate, it doesn't "have" instance
variables because there's no Object to store them in. Instead they
are stored somewhere else. (Where isn't terribly important.)

The instance variables will consume memory, of course.

--
Eric Hodel - drbrain@segment7.net - http://blog.se...
This implementation is HODEL-HASH-9600 compliant

http://trackmap.rob...



Sam Kong

8/8/2006 12:40:00 AM

0

Hi Jeremy,

Jeremy Henty wrote:
> On 2006-08-07, Sam Kong <sam.s.kong@gmail.com> wrote:
>
>> (1..100000).each {|i|...}
>>
>> Now there are 100000 integers in the memory which won't die.
>
> No there aren't. Immediate values don't allocate anything in memory.
> They aren't pointers (even though under the hood Ruby coerces them to
> the same type as non-immediate values that *are* pointers). Immediate
> values aren't garbage collected because there is *nothing* to garbage
> collect. They don't point to anything. What is there to collect?
>
> Think of C. Does "long i ; i = 0 ; i = 1 ; i = 2 ; i = 3" consume any
> more memory than "long i ; i = 0"? No, because the only memory
> allocated is for the long variable "i". The values 0, 1, 2, 3, are
> just constants that are copied (one after the other) into that single
> previously allocated space. Ruby's immediate values are just like C
> longs (in fact, under the hood, they *are* just C longs). Creating
> them doesn't consume memory, it just copies them into a pre-existing
> chunk of memory that was already allocated by the Ruby interpreter.

I understand what you said.
But the integers that I created have additional information.
So not that simple.
Can you read the code I wrote and reconsider such a case?

Thank you.

Sam

--
Posted via http://www.ruby-....

Eric Hodel

8/8/2006 3:30:00 AM

0

On Aug 7, 2006, at 5:40 PM, Sam Kong wrote:

> Jeremy Henty wrote:
>> On 2006-08-07, Sam Kong <sam.s.kong@gmail.com> wrote:
>>
>>> (1..100000).each {|i|...}
>>>
>>> Now there are 100000 integers in the memory which won't die.
>>
>> No there aren't. Immediate values don't allocate anything in memory.
>> They aren't pointers (even though under the hood Ruby coerces them to
>> the same type as non-immediate values that *are* pointers).
>> Immediate
>> values aren't garbage collected because there is *nothing* to garbage
>> collect. They don't point to anything. What is there to collect?
>>
>> Think of C. Does "long i ; i = 0 ; i = 1 ; i = 2 ; i = 3" consume
>> any
>> more memory than "long i ; i = 0"? No, because the only memory
>> allocated is for the long variable "i". The values 0, 1, 2, 3, are
>> just constants that are copied (one after the other) into that single
>> previously allocated space. Ruby's immediate values are just like C
>> longs (in fact, under the hood, they *are* just C longs). Creating
>> them doesn't consume memory, it just copies them into a pre-existing
>> chunk of memory that was already allocated by the Ruby interpreter.
>
> I understand what you said.
> But the integers that I created have additional information.
> So not that simple.
> Can you read the code I wrote and reconsider such a case?

It will work. The instance variables are stored elsewhere.

--
Eric Hodel - drbrain@segment7.net - http://blog.se...
This implementation is HODEL-HASH-9600 compliant

http://trackmap.rob...