# Some odd ball optimization tricks

**URL:** <https://www.ruby-forum.com/t/some-odd-ball-optimization-tricks/193878>\
**Category:** Ruby\
**Created:** [August 26, 2010, 1:53am UTC](https://www.ruby-forum.com/t/some-odd-ball-optimization-tricks/193878 "2010-08-26T01:53:58Z")\
**Posts on this page:** 3\
**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:** [August 26, 2010, 1:53am UTC](https://www.ruby-forum.com/t/some-odd-ball-optimization-tricks/193878/1 "2010-08-26T01:53:58Z")

</div>

Here are two idioms which you may find useful, or at least curious, when  
trying to optimize the heck out of a Ruby script…

require ‘pp’

# Similar to the “autosequence” facility in SQL.

# Useful for replacing a complex key with a very simply POD proxy

object.  
file\_sequence = 0  
file\_index = Hash.new{|hash,key| file\_sequence+=1;hash[key] =  
file\_sequence}

p file\_index[“foo”]  
p file\_index[“foo”]  
p file\_index[“bah”]  
p file\_index[“foo”]  
p file\_index[“bah”]  
pp file\_index

# Similar to “to\_sym”, but can cope with spaces and weird characters…

# So if tom1, tom2, tom3… go out of scope they can be garbage

collected…

# so if you end up just holding tomtom, you have only one copy of “tom”

and  
you can test for

# equality with .object\_id == .object\_id!

one\_true\_string = Hash.new{|hash,string| hash[string] = string}

tom1 = “tom”  
tom2 = “tom”  
tom3 = “#{tom1}”  
tom4 = tom2.clone  
tom5 = “t”+“o”+“m”

toms = [tom1, tom2, tom3, tom4, tom5]

pp toms  
pp toms.collect{|tom| tom.object\_id }  
tomtom = toms.collect{|tom| one\_true\_string[tom] }  
pp tomtom  
pp tomtom.collect{|tom| tom.object\_id }

Running the above results in…  
1  
1  
2  
1  
2  
{“foo”=\>1, “bah”=\>2}  
[“tom”, “tom”, “tom”, “tom”, “tom”]  
[-609503848, -609503908, -609503888, -609503918, -609503978]  
[“tom”, “tom”, “tom”, “tom”, “tom”]  
[-609503848, -609503848, -609503848, -609503848, -609503848]

–  
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

# ======================================================================= This email, including any attachments, is only for the intended addressee. It is subject to copyright, is confidential and may be the subject of legal or other privilege, none of which is waived or lost by reason of this transmission. If the receiver is not the intended addressee, please accept our apologies, notify us by return, delete all copies and perform no other act on the email. Unfortunately, we cannot warrant that the email has not been altered or corrupted during transmission.

---

<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:** [August 26, 2010, 5:38am UTC](https://www.ruby-forum.com/t/some-odd-ball-optimization-tricks/193878/2 "2010-08-26T05:38:44Z")

</div>

On Wednesday, August 25, 2010 06:51:58 pm John C. wrote:

> p file\_index[“foo”]  
> p file\_index[“bah”]  
> pp file\_index

I guess I can think of a few rare instances this might be useful, but  
I’ve  
never had the keys be the bottleneck, or re-used keys enough in a script  
for  
this to matter. Still, interesting.

> # Similar to “to\_sym”, but can cope with spaces and weird characters…

…what?

irb\> ‘foo bar’.to\_sym  
=\> :“foo bar”

> “a@$bcâ˜ƒ!d\t”.to\_sym  
> =\> :“a@$bcâ˜ƒ!d\t”

Worst thing that happens is 1.8 turns my beautiful Unicode into ugly hex  
escapes when pretty-printing, since it’s all just a binary string to  
1.8. But  
if I print it straight out with puts, I get the original Unicode stuff  
back,  
and 1.9.1 handles this gracefully.

I mean, I’ve got a friggin’ SNOWMAN in there. Just what characters have  
you  
discovered that you can’t make a string out of?

And, as it suggests, you can use :“foo” or :‘foo’ as shorthand for the  
above.

> # So if tom1, tom2, tom3… go out of scope they can be garbage
> 
> collected…

Same is true of any string you call to\_sym on.

> you can test for
> 
> # equality with .object\_id == .object\_id!

I don’t know if String is smart enough to do that (I’d hope so), but  
Symbol  
certainly would be.

So what does this solve over just using symbols, other than the fact  
that you  
could manually prune the one\_true\_string hash?

---

<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:** [August 26, 2010, 11:10am UTC](https://www.ruby-forum.com/t/some-odd-ball-optimization-tricks/193878/3 "2010-08-26T11:10:39Z")

</div>

2010/8/26 John C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> p file\_index[“foo”]  
> p file\_index[“foo”]  
> p file\_index[“bah”]  
> p file\_index[“foo”]  
> p file\_index[“bah”]  
> pp file\_index

I prefer

irb(main):001:0\> file\_index = Hash.new {|h,k| h[k] = h.size}  
=\> {}  
irb(main):002:0\> file\_index[“foo”]  
=\> 0  
irb(main):003:0\> file\_index[“foo”]  
=\> 0  
irb(main):004:0\> file\_index[“bah”]  
=\> 1  
irb(main):005:0\> file\_index[“foo”]  
=\> 0  
irb(main):006:0\> file\_index[“bah”]  
=\> 1  
irb(main):007:0\> file\_index  
=\> {“foo”=\>0, “bah”=\>1}

> # Similar to “to\_sym”, but can cope with spaces and weird characters…
> 
> # So if tom1, tom2, tom3… go out of scope they can be garbage collected…
> 
> # so if you end up just holding tomtom, you have only one copy of “tom” and
> 
> you can test for
> 
> # equality with .object\_id == .object\_id!

We have #equal? for that.

> one\_true\_string = Hash.new{|hash,string| hash[string] = string}

Note that this wastes a bit of memory because of the unfrozen string  
Hash optimization:

irb(main):009:0\> one\_true\_string = Hash.new{|hash,string| hash[string] =  
string}  
=\> {}  
irb(main):010:0\> one\_true\_string[“a”]  
=\> “a”  
irb(main):011:0\> one\_true\_string.each {|k,v| puts k.equal? v}  
false  
=\> {“a”=\>“a”}

Better freeze the string:

irb(main):012:0\> one\_true\_string = Hash.new{|hash,string|  
hash[string.freeze] = string}  
=\> {}  
irb(main):013:0\> one\_true\_string[“a”]  
=\> “a”  
irb(main):014:0\> one\_true\_string.each {|k,v| puts k.equal? v}  
true  
=\> {“a”=\>“a”}

Cheers

robert
