On Mon, Apr 11, 2011 at 5:20 AM, Clifford Heath <no / spam.please.net> wrote: > On 04/11/11 10:02, Charles Oliver Nutter wrote: >> >> The special-cased logic for Fixnums and Symbols in hashes is obviously >> done for performance purposes. No matter what you do, checking for >> method redefinitions every single time will have a performance impact. > > Yes. > >> Even checking an inline cache has an impact. > > You are mixing up the situations where there is no sane > case for allowing modifications, from the many fewer > ones where there is. No sane person would want to change > the implementation of 1+1; but someone can and has > implemented Fixnum+Complex. That works because Fixnum > will always call coerce where needed, so there's no need > to guard the optimisations. I think Charly got it exactly right. > In the few remaining cases where there is a good case > for supporting modifications, the minuscule cost of > a check would be justified. A single variable (saying > "this class has been modified from its standard form") > would take up a cache line, but the test would play > into branch prediction, so the actual effect would be > tiny. Frankly, since what you are attempting seems a rather rare case I'd say it should be the way it is. After all, you can easily monkeypatch Hash[] etc. to get the behavior you desire. That way not 99% of usages of Hash have to suffer for 1% needing to code less. I think that is a fair balance. I don't understand why you insist on changing a core class for your rare case of making different classes equivalent and causing potential harm for many, many users of Ruby instead of just going ahead and also monkey patch Hash since you did already so for Fixnum. On one hand you use Ruby's openness to change core classes to achieve what you want but on the other you seem to refuse to change another to make your change complete. The only reason for this that I can detect is that you were surprised and your expectations were not met. But now since you have learned otherwise what stops you from dealing with the situation in the pragmatic way that is so typical for Ruby? > I know you guys have done amazing thing to achieve the > performance that we now have, but please don't forget > why people choose Ruby; it's clean and consistent. ... most of the time. But it also tries to balance reasonable usability with above than awful performance. > Another thing that could be done to assist; make sure > that a Hash only ever calls eql? on objects in the hash, > not on lookup keys. At least that way, if a non-standard > object is in the hash, it can still be found using values > that *it* considers equivalent. This change would cost > *nothing*, it would just make Ruby more consistent. But it also would not have any positive impact for all others plus that a change always brings a certain amount of risk of introducing errors. Note though, that there might be situations where you want the exact opposite: you have a Fixnum key and pass a SomethingFixnumLinke lookup key and want the match to succeed. You can only have it one way. You happen to need the way that is not possible right now. Apart from that it feels more natural to me to let the key passed in compare internal key for equivalence because this key is what should determine whether I have a match or not. >> In this case I think there's a fine line between consistency and >> zealotry. The *vast* majority of Ruby users will never reopen and >> modify Fixnum or Symbol, > > People don't do it because it doesn't work, not because > it wouldn't be useful. How do you know? > Inability to make classes that act > like numbers is perhaps the biggest wart on an otherwise > clean language, on a par with Javascript using float for > all numbers. We *can* make classes that act like numbers (as has been demonstrated often enough). And this works remarkably well. >> We've been more conservative than other impls, even. > > and yet JRuby's Hash optimises both eql? and hash for Fixnums, > where MRI only optimises hash. It is in the nature of optimizations that they are done differently on different platforms. Actually they have to because characteristics of all platforms are different. Cheers robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/