title: Slow equality evaluation for identical objects (x == x)
body: <p>Is there any reason <code>x == x</code> is not evaluated quickly? I was hoping <code>__eq__</code> would check if its two arguments are identical, and if so return True instantly. But it doesn't do it:</p>
  
  <pre><code>s = set(range(100000000))
  s == s # this doesn't short-circuit, so takes ~1 sec
  </code></pre>
  
  <p>For built-ins, <code>x == x</code> always returns True I think? For user-defined classes, I guess someone could define <code>__eq__</code> that doesn't satisfy this property, but is there any reasonable use case for that?</p>
  
  <p>The reason I want <code>x == x</code> to be evaluated quickly is because it's a huge performance hit when <a href="https://stackoverflow.com/a/12726843/336527">memoizing functions with very large arguments</a>:</p>
  
  <pre><code>from functools import lru_cache
  @lru_cache()
  def f(s):
      return sum(s)
  large_obj = frozenset(range(50000000))
  f(large_obj) # this takes &gt;1 sec every time
  </code></pre>
  
  <p>Note that the reason @lru_cache is <em>repeatedly</em> slow for large objects is not because it needs to calculate <code>__hash__</code> (this is only done once and is then hard-cached as <a href="https://stackoverflow.com/a/12726793/336527">pointed out</a> by @jsbueno), but because the dictionary's hash table needs to execute <code>__eq__</code> <em>every time</em> to make sure it found the right object in the bucket (equality of hashes is obviously insufficient).</p>
  
  <p>UPDATE:</p>
  
  <p>It seems it's worth considering this question separately for three situations.</p>
  
  <p>1) User-defined types (i.e., not built-in / standard library).</p>
  
  <p>As @donkopotamus pointed out, there are cases where <code>x == x</code> should not evaluate to True. For example, for <code>numpy.array</code> and <code>pandas.Series</code> types, the result is intentionally not convertible to boolean because it's unclear what the natural semantics should be (does False mean the container is empty, or does it mean all items in it are False?).</p>
  
  <p>But here, there's no need for python to do anything, since the users can always short-circuit <code>x == x</code> comparison themselves if it's appropriate:</p>
  
  <pre><code>def __eq__(self, other):
    if self is other:
      return True
    # continue normal evaluation
  </code></pre>
  
  <p>2) Python built-in / standard library types.</p>
  
  <p>a) Non-containers.</p>
  
  <p>For all I know the short-circuit may already be implemented for this case - I can't tell since either way it's super fast.</p>
  
  <p>b) Containers (including <code>str</code>).</p>
  
  <p>As @Karl Knechtel commented, adding short-circuit may hurt total performance if the savings from short-circuit are outweighed by the extra overhead in cases where <code>self is not other</code>. While theoretically possible, even in that case the overhead is a small in relative terms (container comparison is never super-fast). And of course, in cases where short-circuit helps, the savings can be dramatic.</p>
  
  <p>BTW, it turns out that <code>str</code> does short-circuit: comparing huge identical strings is instant.</p>