Tim Peters <[email protected]> added the comment:
For me, it's largely because you make raw assertions with extreme confidence
that the first thing you think of off the top of your head can't possibly make
anything else worse. When it turns out it does make some things worse, you're
equally confident that the second thing you think of is (also) perfect.
So far we don't even have a real-world test case, let alone a coherent
characterization of "the problem":
"""
all involving negative numbers) due to the same underlying mathematical reason.
"""
is a raw assertion, not a characterization. The only "mathematical reason" you
gave before is that "j odd implies j^(-2) == -j, so that m*(j^(-2)) == -m".
Which is true, and a good observation, but doesn't generalize as-is beyond -2.
Stuff like this from the PR doesn't inspire confidence either:
"""
MULTIPLIER = (1000003)**3 + 2 = 1000009000027000029: the multiplier should be
big enough and the original 20-bit number is too small for a 64-bit hash. So I
took the third power. Unfortunately, this caused a sporadic failure of the
testsuite on 32-bit systems. So I added 2 which solved that problem.
"""
Why do you claim the original was "too small"? Too small for what purpose? As
before, we don't care whether Python hashes "act random". Why, when raising it
to the third power apparently didn't work, did you pull "2" out of a hat? What
was _the cause_ of the "sporadic failure" (whatever that means), and why did
adding 2 fix it? Why isn't there a single word in _the code_ about where the
mystery numbers came from?:
You're creating at least as many mysteries as you're claiming to solve.
We're not going to change such heavily used code on a whim.
That said, you could have easily enough _demonstrated_ that there's potentially
a real problem with a mix of small integers of both signs:
>>> from itertools import product
>>> cands = list(range(-10, -1)) + list(range(9))
>>> len(cands)
18
>>> _ ** 4
104976
>>> len(set(hash(t) for t in product(cands, repeat=4)))
35380
And that this isn't limited to -2 being in the mix (and noting that -1 wasn't
in the mix to begin with):
>>> cands.remove(-2)
>>> len(cands) ** 4
83521
>>> len(set(hash(t) for t in product(cands, repeat=4)))
33323
If that's "the problem", then - sure - it _may_ be worth addressing. Which we
would normally do by looking for a minimal change to code that's been working
well for over a decade, not by replacing the whole thing "just because".
BTW, continuing the last example:
>>> c1 = Counter(hash(t) for t in product(cands, repeat=4))
>>> Counter(c1.values())
Counter({1: 11539, 2: 10964, 4: 5332, 3: 2370, 8: 1576, 6: 1298, 5: 244})
So despite that there were many collisions, the max number of times any single
hash code appeared was 8. That's unfortunate, but not catastrophic.
Still, if a small change could repair that, fine by me.
----------
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue34751>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com