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: Optimize builtin functions min() and max()
Type: performance Stage: patch review
Components: Interpreter Core Versions: Python 3.11
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Dennis Sweeney, colorfulappl, erlendaasland
Priority: normal Keywords: patch

Created on 2021-12-29 10:04 by colorfulappl, last changed 2022-04-11 14:59 by admin.

Files
File name Uploaded Description Edit
bench-minmax.py erlendaasland, 2021-12-30 13:06
Pull Requests
URL Status Linked Edit
PR 30286 open colorfulappl, 2021-12-29 10:10
Messages (3)
msg409299 - (view) Author: (colorfulappl) * Date: 2021-12-29 10:04
https://github.com/faster-cpython/ideas/discussions/199
msg409367 - (view) Author: Erlend E. Aasland (erlendaasland) * (Python triager) Date: 2021-12-30 13:06
Repeating my comment on GH-30286: If we are touching `min()` and `max()`, it would make sense, IMO, to port them to Argument Clinic. FTR, Argument Clinic got `*args` support in GH-18609 / bpo-20291.

@colorfulappl made a "competing" branch using AC on his local fork[^1]. However, that branch contained a bug with the key function; I made an amended version[^2] for benchmarking. Here's some micro-benchmarks from optimised builds on macOS 12.1 w/Clang 13:

```
+---------------------------------------------------------+---------+-----------------------+----------------------+
| Benchmark                                               | main    | GH-30286              | GH-30286-ac          |
+=========================================================+=========+=======================+======================+
| max(a, b)                                               | 193 ns  | 74.1 ns: 2.60x faster | 179 ns: 1.08x faster |
+---------------------------------------------------------+---------+-----------------------+----------------------+
| max(a, b, c, d, e)                                      | 273 ns  | 126 ns: 2.17x faster  | 260 ns: 1.05x faster |
+---------------------------------------------------------+---------+-----------------------+----------------------+
| max([a, b])                                             | 267 ns  | 185 ns: 1.44x faster  | 239 ns: 1.12x faster |
+---------------------------------------------------------+---------+-----------------------+----------------------+
| max([a, b, c, d, e])                                    | 345 ns  | 259 ns: 1.33x faster  | 312 ns: 1.10x faster |
+---------------------------------------------------------+---------+-----------------------+----------------------+
| max((a,), (b,), key=lambda x: x[0])                     | 707 ns  | 444 ns: 1.59x faster  | 513 ns: 1.38x faster |
+---------------------------------------------------------+---------+-----------------------+----------------------+
| max((a,), (b,), (c,), (d,), (e,), key=lambda x: x[0])   | 1.12 us | 831 ns: 1.35x faster  | 930 ns: 1.20x faster |
+---------------------------------------------------------+---------+-----------------------+----------------------+
| max([(a,), (b,)], key=lambda x: x[0])                   | 786 ns  | 561 ns: 1.40x faster  | 570 ns: 1.38x faster |
+---------------------------------------------------------+---------+-----------------------+----------------------+
| max([(a,), (b,), (c,), (d,), (e,)], key=lambda x: x[0]) | 1.19 us | 981 ns: 1.22x faster  | 981 ns: 1.22x faster |
+---------------------------------------------------------+---------+-----------------------+----------------------+
| max([], default=-1)                                     | 484 ns  | 177 ns: 2.73x faster  | 188 ns: 2.57x faster |
+---------------------------------------------------------+---------+-----------------------+----------------------+
| Geometric mean                                          | (ref)   | 1.68x faster          | 1.29x faster         |
+---------------------------------------------------------+---------+-----------------------+----------------------+
```



[^1]: https://github.com/colorfulappl/cpython/commit/29b9559de31ae19e8d127d7a3063494b2d9791b0
[^2]: https://github.com/erlend-aasland/cpython/tree/gh-30286-ac
msg409421 - (view) Author: Dennis Sweeney (Dennis Sweeney) * (Python committer) Date: 2021-12-31 14:22
Kind of like what's mentioned at https://github.com/faster-cpython/ideas/discussions/131 , it may be interesting to explore implementing min()/max() in Pure python, considering recent specializations to COMPARE_OP, and potential future specializations of FOR_ITER.
History
Date User Action Args
2022-04-11 14:59:53adminsetgithub: 90350
2021-12-31 14:22:47Dennis Sweeneysetnosy: + Dennis Sweeney
messages: + msg409421
2021-12-30 13:06:30erlendaaslandsetfiles: + bench-minmax.py
nosy: + erlendaasland
messages: + msg409367

2021-12-29 10:10:13colorfulapplsetkeywords: + patch
stage: patch review
pull_requests: + pull_request28500
2021-12-29 10:05:14colorfulapplsettype: performance
2021-12-29 10:04:55colorfulapplcreate