2011/6/21 IƱaki Baz Castillo <ibc / aliax.net>:
> 2011/6/21 Robert Klemme <shortcutter / googlemail.com>:
>> See Adam's and Josh's replies: a Hash is generally unordered.
>> However, what do you need this for? If it is for debugging purposes
>> then you might as well override #inspect on a per instance basis or
>> change it in Hash (not recommended).
>
> Hi, I don't understand your comment.

Sorry, my dog pressed "sent mail".

I meant that I don't understand the point of your comments. In Ruby
1.9 Hashes are ordered. I cannot change the order after creating them,
but if you inspect elements of a Hash you get them in the order in
which they were inserted. This is valid and useful for me (in my
case).


>> If you need that for other
>> reasons then maybe a tree might be a better choice. There is for
>> example
>> http://raa.ruby-lang.org/project/ruby-rbtree/

I already worker with rbtree. The only difference (or one of them) is
the way in which keys are inserted. rbtree requires all the keys being
the same class. In my tests rbtree is better for deleting elements but
worse than a Hash for inserting them.

You can check it:

------------------------------------------
require "benchmark"

@hash = {}
@rbtree = RBTree.new


TIMES = ARGV[0] ? ARGV[0].to_i : 10000
WORD = "z9hG4bK".freeze


def gen_word(word, n)
  case word
  when :fixed_begin
    WORD + n.to_s
  when :dynamic_begin
    n.to_s + WORD
  end
end

def test(word)
  puts
  case word
  when :fixed_begin
    puts "Using word:  \"z9hG4bK\" + n.to_s"
  when :dynamic_begin
    puts "Using word:  n.to_s + \"z9hG4bK\""
  end

  puts
  printf "- Hash insertion:    "
  puts time_hash_insertion = Benchmark.realtime {
    TIMES.times do |n|
      @hash[gen_word(word, n)] = 12345
    end
  }

  printf "- RBTree insertion:  "
  puts time_rbtree_insertion = Benchmark.realtime {
    TIMES.times do |n|
      @rbtree[gen_word(word, n)] = 12345
    end
  }

  puts
  printf "- Hash deletion:     "
  puts time_hash_deletion = Benchmark.realtime {
    TIMES.times do |n|
      @hash.delete(gen_word(word, n))
    end
  }

  printf "- RBTree deletion:   "
  puts time_rbtree_deletion = Benchmark.realtime {
    TIMES.times do |n|
      @rbtree.delete(gen_word(word, n))
    end
  }

  puts
  puts "TOTAL:"
  puts "- Hash insertion + deletion:    #{time_hash_insertion +
time_hash_deletion}"
  puts "- RBTree insertion + deletion:  #{time_rbtree_insertion +
time_rbtree_deletion}"
end


puts "Entries:  #{TIMES}"
puts
test(:fixed_begin)
puts
test(:dynamic_begin)
------------------------------------------



Results:

------------------------
Entries:  10000


Using word:  "z9hG4bK" + n.to_s

- Hash insertion (seconds):    0.020041227340698242
- RBTree insertion (seconds):  0.041683197021484375

- Hash deletion (seconds):     0.035521745681762695
- RBTree deletion (seconds):   0.023290157318115234

TOTAL:
- Hash insertion + deletion (seconds):    0.05556297302246094
- RBTree insertion + deletion (seconds):  0.06497335433959961


Using word:  n.to_s + "z9hG4bK"

- Hash insertion (seconds):    0.019947528839111328
- RBTree insertion (seconds):  0.0295107364654541

- Hash deletion (seconds):     0.029720067977905273
- RBTree deletion (seconds):   0.01738262176513672

TOTAL:
- Hash insertion + deletion (seconds):    0.0496675968170166
- RBTree insertion + deletion (seconds):  0.04689335823059082
------------------------


-- 
Iaki Baz Castillo
<ibc / aliax.net>