2010/8/26 John Carter <john.carter / tait.co.nz>:
> 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

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


-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/