New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
int << 0: return the number unmodified #65621
Comments
I propose to add a micro-optimization for int << 0: return the number unmodified. See attached patch. |
Every branch has a cost (in particular, it tends to contaminate global branch prediction tables and blow other code out of the L1 code cache). The cost isn't big, but branches shouldn't be added unless we know there is a real benefit. I would think that in real-world code, this branch will almost never be taken. The common case will pay a price (albiet a small one) for almost zero benefit. |
I think that x << 0 is common even if it's not written like that (it's more The benefit is to reduce the memory footprint. Can you sow the overhead of the branch in a microbenchmark? The test is *If* it's possible to notice an overhead, we can maybe use GCC macro |
Conversely, can you show a case where this optimisation provides a benefit in real code? We should be looking for a reason *to* apply the patch, not a reason *not* to apply the patch. |
The reason to apply the patch is to reduce the memory footprint. |
Reduce the memory footprint in which actual workload? This looks rather gratuitous to me. |
BTW, there's also a behaviour change here. Before the patch: >>> True << 0
1 After the patch: >>> True << 0
True Which demonstrates another good reason to avoid trivial-looking optimisations: it's far too easy to accidentally change behaviour. |
Hi, def test_shifted_true(self):
self.assertEqual(True << 0, 1)
self.assertEqual(True << 1, 2) |
Francisco: I'd say that was a good idea. Would you like to propose a patch? (ie: figure out where it should go) |
Use assertIs, since True == 1, but True is not 1. |
New changeset ef49aaad3812 by Victor Stinner in branch '3.4': New changeset 3da4aed1d18a by Victor Stinner in branch 'default': |
Ok, 3 core dev are opposed to the change, I close the issue. I added a test on bool >> int and bool << int to ensure that the result is an int. |
I Victor you were so fast, I started with one patch also in bool (at least the place was right). The problem is that I was getting some extrage (for me at least). As far I hat: def test_shifted_true(self):
with self.assertRaises(ValueError):
True << -1
self.assertIs(True << 0, 1)
self.assertIs(True << 1, 2)
self.assertEqual(True << 63, 1 << 63)
self.assertIs(True << 63, 1 << 63) And I'm getting: ====================================================================== Traceback (most recent call last):
File "/home/ci/Prog/cpython/src/Lib/test/test_bool.py", line 349, in test_shifted_true
self.assertIs(True << 63, 1 << 63)
AssertionError: 9223372036854775808 is not 9223372036854775808 That's: >>> type(True<<63)
<class 'int'>
>>> type(1<<63)
<class 'int'> hg tip What I'm doing wrong? >>> type(True<<63)
<class 'int'>
>>> type(1<<63)
<class 'int'> hg tip What I was doing wrong? Thanks in advance! |
The "is" operator should only be used to compare identical objects. Small integers (range -5..255 if I remember correctly) are singletons. I prefer to not rely on this implementation detail in a unit test of the Python standard library. |
Arfrever's advice was misleading...the test would have needed to be assertIsNot(True << 0, 1), but the fact that True is not preserved is not really what we want to test. What we want to test is that the return value is of type 'int', which is what Victor's test checks. |
Arfrever pointed out on irc that I misread. It would indeed be assertIs(True << 0, 1), but that wouldn't make a good test because the fact that '1 is 1' is an implementation detail of CPython and can't be relied upon. |
Thank you for the explanations! for 2.7.6 type(2 << 62) is <type 'long'> and type(2 << 61) is Is that still relevant? or is too much detail and we should stop here. Regards, |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: