This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Minor branch optimization in set implementation
Type: enhancement Stage: patch review
Components: Interpreter Core Versions: Python 3.6
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: rhettinger Nosy List: rhettinger, serhiy.storchaka
Priority: low Keywords: patch

Created on 2015-07-07 08:38 by serhiy.storchaka, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
set_branch_optimizations.patch serhiy.storchaka, 2015-07-07 08:38 review
Messages (5)
msg246395 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2015-07-07 08:38
For now multiple set functions call helpers that returns one of three possible values (0, 1, and -1 for error) and then analyze return code in the loop.

    while (...) {
        rv = some_set_operation();
        if (rv < 0) {
            // clean up
            return NULL;
        }
        if (rv) {
            other_set_operation();
        }
        // if (rv == 0) do nothing
    }

If rv is 0 or 1, it is tested two times. If rv is -1 (unlikely), it is tested only once.

It is possible to rewrite testing in other way:

    while (...) {
        rv = some_set_operation();
        if (rv != 0) { // 1 or -1
            if (rv < 0) {
                // clean up
                return NULL;
            }
            other_set_operation();
        }
    }

Now if rv is 0 (common case), it is tested only once, and likely the test jump will be merged with unconditional loop jump.

I have no benchmarking results, but I suppose that such rewritting will generate better machine code.
msg246417 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2015-07-07 15:27
I believe this patch will make matters worse.  The current pair of tests can essentially be run in parallel and the one with rv==-1 is highly predictable (essentially zero cost).
msg246418 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2015-07-07 15:28
FWIW, I had tried some variants of this a one point and saw no benefit at all.
msg246422 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2015-07-07 16:09
Then feel free to close this issue. I'm not very experienced with modern superscalar CPUs.
msg246429 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2015-07-07 17:12
Thanks.

FWIW, there was one other issue.  The code is set-up to accommodate aggressive in-lining so that the code in set_contains(), for example, the sets a return value of -1 gets combined with the downstream test for -1 and the pairs gets folded away in the generated code.  Combining the -1 and the zero test gets in the way of this.
History
Date User Action Args
2022-04-11 14:58:18adminsetgithub: 68770
2015-07-07 17:12:54rhettingersetstatus: open -> closed
resolution: rejected
messages: + msg246429
2015-07-07 16:09:11serhiy.storchakasetmessages: + msg246422
2015-07-07 15:28:54rhettingersetmessages: + msg246418
2015-07-07 15:28:00rhettingersetpriority: normal -> low

messages: + msg246417
2015-07-07 15:24:56rhettingersetassignee: rhettinger
2015-07-07 08:38:26serhiy.storchakacreate