Instance_eval vs attr_reader

Hi, I’m new in forum; even newer in programming.
I would like to know what is faster (uses less memory) to retrieve data?
I use ruby 1.8 series.

my_class.instance_eval(@var) or
my_class.var #using attr_reader

My question is based on the fact one have to asign a symbol to use the
‘attr_reader’ type thus creating ‘memory leaks’, while not in the
former. But I’m not sure.

Thank You.

On Thursday 25 November 2010 21:07:13 Joe P. wrote:

Thank You.

The former wouldn’t work, because it would call instance_eval passing
the
value of the instance variable @val of whichever object is self at the
moment
(not of my_class). To make it work as you wanted, you’d need to use

my_class.instance_eval(’@var’)

that is, you should pass a string containing the text ‘@var’ to instance
eval.
However, attr_reader (and attr_writer and attr_accessor) are created
precisely
for the task you describe, so you can safely assume they can do it well.
instance_eval (like eval and class_eval) are usually kept as last
resource,
when there’s no other way to do what you want. They’re more generic and
so,
most likely, less efficient than any other more specific tool.

I hope this helps

Stefano

On Thu, Nov 25, 2010 at 1:07 PM, Joe P. [email protected] wrote:

Hi, I’m new in forum; even newer in programming.
I would like to know what is faster (uses less memory) to retrieve data?
I use ruby 1.8 series.

my_class.instance_eval(@var) or
my_class.var #using attr_reader

I guess “my_class” is meant to be an instance and not necessarily a
class. Btw, there’s also #instance_variable_get and
#instance_variable_set.

My question is based on the fact one have to asign a symbol to use the
‘attr_reader’ type thus creating ‘memory leaks’, while not in the
former. But I’m not sure.

If you’re concerned with performance you can easily measure it (see
module Benchmark) and can work with hard facts. However, this would
almost certainly be a micro optimization and since we know that
“premature optimization is the root of all evil” I would first use the
proper approach (i.e. define accessors).

Kind regards

robert

On Thu, Nov 25, 2010 at 1:07 PM, Joe P. [email protected] wrote:

Hi, I’m new in forum; even newer in programming.
I would like to know what is faster (uses less memory) to retrieve data?
I use ruby 1.8 series.

speed and memory requirements are not related to each other. It’s
faster to store a large value in memory if it takes a million cycles
to calculate it, and only 1000 to retrieve it, for example.

my_class.instance_eval(@var) or
my_class.var #using attr_reader

My question is based on the fact one have to asign a symbol to use the
‘attr_reader’ type thus creating ‘memory leaks’, while not in the
former. But I’m not sure.

You only create a memory leak in Ruby, if your objects are never
garbage collected. So, if you create an object with 10 000 symbols,
and immediately discard it, the memory will be reclaimed.

Though, the question is: Why worry about memory, especially a tiny
chunk of it in case of symbols, compared to the Ruby interpreter?

As Robert pointed out, you need to measure (with Benchmark and memory
profiling), before you should optimize where an optimization may not
be needed (or even effective!).


Phillip G.

Though the folk I have met,
(Ah, how soon!) they forget
When I’ve moved on to some other place,
There may be one or two,
When I’ve played and passed through,
Who’ll remember my song or my face.

On Fri, Nov 26, 2010 at 12:25 PM, Joe P. [email protected] wrote:

a
attr_reader-line-of-code every time one needs to access a variable from
outside. But is it practical, in the long run?

Most Ruby programs use that approach.

@Stefano C.: With the new example @var none-string works.
@Robert K.: I can’t use Benchmark at the moment.

Why? It’s not difficult:

12:40:07 ~$ ruby19 -r benchmark <<CODE

T = 10000
Benchmark.bm 10 do |x|
x.report(“foo”) { T.times { 1 + 2 } }
x.report(“bar”) { T.times { 1 * 2 } }
end
CODE
user system total real
foo 0.000000 0.000000 0.000000 ( 0.002000)
bar 0.000000 0.000000 0.000000 ( 0.002000)
12:41:04 ~$

Replace “1+2” and “1*2” with the code you want to compare. Of course,
you can put this in a script.

Again, stop wondering, start measuring.

@Phillip G.: If I’m not mistaken, symblos are NEVER G.collected.
That’s my concern. Since I’m making dozen of symbols. Also, can you give
me a good link on how memory/speed works in computer programming. I use
google, but I don’t think I’m using the right keywords.

“Dozens” is not actually what I would call “many”. Don’t worry.

Cheers

robert

Thanks for everyone who replied. I MADE A MISTAKE IN MY ORIGINAL
EXAMPLE.
What I meant to compare speed/memory wise was:

my_class.instance_eval {@var} vs. #NOT my_class.instance_eval(@var)
my_class.var #using attr_reader

So the ‘argument’ is a block. Does it make any difference at all. What I
understand is that by using instance_eval self becomes my_class and one
can access the variable. This seems to my much easier that having to add
a
attr_reader-line-of-code every time one needs to access a variable from
outside. But is it practical, in the long run?

@Stefano C.: With the new example @var none-string works.
@Robert K.: I can’t use Benchmark at the moment.
@Phillip G.: If I’m not mistaken, symblos are NEVER G.collected.
That’s my concern. Since I’m making dozen of symbols. Also, can you give
me a good link on how memory/speed works in computer programming. I use
google, but I don’t think I’m using the right keywords.

Once again: Thank You Very Much.

On Fri, Nov 26, 2010 at 12:25 PM, Joe P. [email protected] wrote:

@Phillip G.: If I’m not mistaken, symblos are NEVER G.collected.
That’s my concern. Since I’m making dozen of symbols. Also, can you give
me a good link on how memory/speed works in computer programming. I use
google, but I don’t think I’m using the right keywords.

124 * 8 bytes << 2 GB of address space total (on a 32 bit system). :wink:

As for speed and memory comparisons: The question is what you are
looking at, both in hardware and software, so I can talk only in the
most general terms:

  • RAM is faster than a hard drive for memory access, but is vastly
    slower than L2 cache.

  • CISC architectures are slower, but more versatile than RISC
    architectures (CPU design).

  • Algorithms are compared on speed and accuracy / stability.

  • Doing multiplication of large integers is slower than performing
    addition.

This begets the question what of those matters to you and your code.

A couple of keywords that might be of interest:

  • memory profiling
  • Benchmarking and micro benchmarks
  • Big O notation (for algorithms)

In the end, you’ll have to make trade offs between speed of code
execution, speed of code development, ease of code maintenance, and
available resources (both to you, and your target). You have to write
code differently for a PLC than for a current gen desktop computer
than for a smart phone, and all bets are off when writing a device
driver.

But for now, if you are new to programming, just learn to program, and
worry about performance later. Once you have the right habits (like:
writing unit tests, either in test driven development, or in bug
hunting; Don’t Repeat Yourself; You Ain’t Gonna Need It; and many
more), you’ll find it much easier to evaluate code for performance
issues, and you’ll have an idea which tool to use in which situation.


Phillip G.

Though the folk I have met,
(Ah, how soon!) they forget
When I’ve moved on to some other place,
There may be one or two,
When I’ve played and passed through,
Who’ll remember my song or my face.