> From: Ben Tilly [mailto:ben_tilly / hotmail.com] > Sent: Tuesday, February 27, 2001 08:52 PM > To: ruby-talk ML > Subject: [ruby-talk:11739] Comparison Caching > > > OK, this is my latest entry in the "solve testing > equality with a recursive data structure" discussion. > Unfortunately on my machine the test suite that others > are using fails miserably after exhausting the stack, > but when I scale it back this seems to be a tad faster. > But note that it is optimized for the case where we > see each object compared to very few others. > > I have changed names of methods a little bit. Feel > free to change them back. I also did both <=> and > == (but only for arrays). > > I tried a caching scheme of hashes of hashes, that > was consistently somewhat slower. But there are > definitely cases where it would be faster... > > Cheers, > Ben [...] As discussed in a private email your and my (optimisitic) algorithm are identical(modulo details). My main objection about your current version is that it depends on the Hash-Hash realization of an ``Idbag'' and does not abstract this away as an implementation detail. In principle a Hash - Hash (of Integer) encoding and the (Sym)Id_pair encoding are actually more or less identical and in an ideal version you would write the whole ID-bag class in C. (I appended a version of IdBag based on Hash which is a bit faster on my Machine then my original (faster module (Non symetric) IdBag2) version - the main reason is that no intermediate IdPair Objects are created - I don't know if if Guy's C-implementation does the same thing). I also think that your objections towards symmetrization - i.e. swapping are not valid since they cost very little compared to the reminder division invoked in any hashing scheme and running the interpreter it self of course (in my test it makes virtually non difference if you swap or don't swap - even so swapping does not gain anything in the ``examples'') - swapping IMO simply feels more robust. Christoph ------------ module IdBag1 class IdBag def initialize @bag = {} end attr_accessor :bag def sym_pair_include? a, b if a < b then if (tmp =@bag[a]) return tmp[b] else false end else if (tmp =@bag[b]) return tmp[a] else false end end end def sym_pair_include a, b if a < b then if (tmp= @bag[a]) tmp[b] = true else tmp= @bag[a] ={} tmp[b] = true end else if (tmp= @bag[b]) tmp[a] = true else tmp= @bag[b] ={} tmp[a] = true end end end end end module IdBag2 class IdBag def initialize @bag = {} end def include_pair a, b @bag[IdPair.new a.id,b.id] =true end def included_pair? a,b @bag.key? (IdPair.new a.id,b.id) end private class IdPair def initialize l,r @l = l; @r = r end def hash; @l end def eql?(other) @r.eql? (other.r) end protected attr_reader :l, :r end end end