# New Optimization idea

**URL:** <https://www.ruby-forum.com/t/new-optimization-idea/56073>\
**Category:** Ruby\
**Created:** [March 27, 2006, 11:18pm UTC](https://www.ruby-forum.com/t/new-optimization-idea/56073 "2006-03-27T23:18:26Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![amin1426](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/4da419/32.png) [@amin1426](https://www.ruby-forum.com/u/amin1426)\
**Post date:** [March 27, 2006, 11:18pm UTC](https://www.ruby-forum.com/t/new-optimization-idea/56073/1 "2006-03-27T23:18:26Z")

</div>

I have a couple of classes like so…

class Foo  
def step1  
@mine = Hash.new  
# Perhaps stuff things into @mine  
end

def step2  
@mine.each\_pair do |key,value|  
# Do stuff  
end  
end  
end

Profiling with my “new” profiler shows that I’m creating many many Hash  
objects, probably way more than I need. In fact most of them are empty.

Optimization trick…

class Object  
FROZEN\_EMPTY\_HASH = Hash.new.freeze  
end

class Foo  
@@hash\_cache = Hash.new

def step1  
@mine = @@hash\_cache  
# Perhaps stuff things into @mine  
if @mine.empty?  
@mine = FROZEN\_EMPTY\_HASH  
else  
@@hash\_cache = Hash.new  
end  
end

def step2  
@mine.each\_pair do |key,value|  
# Do stuff  
end  
end  
end

John C. Phone : (64)(3) 358 6639  
Tait Electronics Fax : (64)(3) 359 4632  
PO Box 1645 Christchurch Email : removed\_email\_address@domain.invalid  
New Zealand

Carter’s Clarification of Murphy’s Law.

“Things only ever go right so that they may go more spectacularly wrong  
later.”

From this principle, all of life and physics may be deduced.

---

<div class="post-metadata">

**Author:** ![amin1426](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/4da419/32.png) [@amin1426](https://www.ruby-forum.com/u/amin1426)\
**Post date:** [March 28, 2006, 9:00pm UTC](https://www.ruby-forum.com/t/new-optimization-idea/56073/2 "2006-03-28T21:00:10Z")

</div>

John C. wrote:

> ```
> # Do stuff
> 
> ```
> 
> class Object  
> @mine = FROZEN\_EMPTY\_HASH  
> end  
> You could as well leave the member nil and change the getter  
> appropriately:

class Foo  
def mine() @mine || FROZEN\_EMPTY\_HASH end  
def step2() mine.each\_pair …  
end

Or do the test in step2…  
@mine and @mine.each\_pair …

Kind regards

```
robert
```

---

<div class="post-metadata">

**Author:** ![amin1426](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/4da419/32.png) [@amin1426](https://www.ruby-forum.com/u/amin1426)\
**Post date:** [March 28, 2006, 11:47pm UTC](https://www.ruby-forum.com/t/new-optimization-idea/56073/3 "2006-03-28T23:47:17Z")

</div>

On Wed, 29 Mar 2006, Robert K. wrote:

> You could as well leave the member nil and change the getter appropriately:
> 
> class Foo  
> def mine() @mine || FROZEN\_EMPTY\_HASH end  
> def step2() mine.each\_pair …  
> end
> 
> Or do the test in step2…  
> @mine and @mine.each\_pair …

I didn’t want to do that since @mine.each and .has\_key? was going to be  
evaluated often and in many places.  
ie. The optimization tweak would have been a shot gun  
hack all over the place.

However, if anybody had listened to me about the Null Object pattern and  
nil…

I wouldn’t have had to do anything.

John C. Phone : (64)(3) 358 6639  
Tait Electronics Fax : (64)(3) 359 4632  
PO Box 1645 Christchurch Email : removed\_email\_address@domain.invalid  
New Zealand

Carter’s Clarification of Murphy’s Law.

“Things only ever go right so that they may go more spectacularly wrong  
later.”

From this principle, all of life and physics may be deduced.

---

<div class="post-metadata">

**Author:** ![amin1426](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/4da419/32.png) [@amin1426](https://www.ruby-forum.com/u/amin1426)\
**Post date:** [March 29, 2006, 11:54pm UTC](https://www.ruby-forum.com/t/new-optimization-idea/56073/4 "2006-03-29T23:54:35Z")

</div>

On Mar 27, 2006, at 1:18 PM, John C. wrote:

> ```
> # Do stuff
> end
> 
> ```
> 
> end  
> end
> 
> Profiling with my “new” profiler shows that I’m creating many many  
> Hash objects, probably way more than I need. In fact most of them  
> are empty.
> 
> Optimization trick…

Maybe it is just me, but I find your original code much easier to  
read and intuitive than your second version. There is just too much  
wonky-thought going on in the second version and it’ll make it easy  
to get it wrong (esp if this pattern spreads throughout a large code  
base). I don’t know what your real code is doing, but creating empty  
hashes seems fine to me. They don’t actually cost all that much:

% time ruby -e ‘1\_000\_000.times do Hash.new; end’

real 0m7.107s  
user 0m3.432s  
sys 0m0.101s

(with itunes running in the background no less)

One suggestion I could make is to recycle if you really are making  
too many empty hashes. If you are running step1/2 in a loop and doing  
a lot of such work, only reinstantiate @mine if you need to:

def initialize  
@mine = Hash.new  
end

def step1  
@mine = Hash.new unless @mine.empty?  
# …  
end

That is only a teeny change to your original logic and meets your  
goals of creating less hashes. I can read that and grok the intent  
immediately. I can’t with your rewrite.

–  
\_why: zenspider’s most intense moments of solice are immediately  
following the slaughter […]  
\_why: that topknot’s the only thing keeping a lid on the righteous anger  
bricolage: yeah, that and his flagrant obsession with dvorak

---

<div class="post-metadata">

**Author:** ![amin1426](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/4da419/32.png) [@amin1426](https://www.ruby-forum.com/u/amin1426)\
**Post date:** [March 31, 2006, 8:32am UTC](https://www.ruby-forum.com/t/new-optimization-idea/56073/5 "2006-03-31T08:32:36Z")

</div>

On Thu, 30 Mar 2006, Ryan D. wrote:

> Maybe it is just me, but I find your original code much easier to read and  
> intuitive than your second version. There is just too much wonky-thought  
> going on in the second version and it’ll make it easy to get it wrong (esp if

Like any optimization, premature, it’s the root of all programming evil.  
In my case profiling showed up a case where I was starting to consume  
significant non-GC’able memory resources which were slowing the system  
as  
a whole.

In this case it was worth it. In general, no.

John C. Phone : (64)(3) 358 6639  
Tait Electronics Fax : (64)(3) 359 4632  
PO Box 1645 Christchurch Email : removed\_email\_address@domain.invalid  
New Zealand

Carter’s Clarification of Murphy’s Law.

“Things only ever go right so that they may go more spectacularly wrong  
later.”

From this principle, all of life and physics may be deduced.
