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 floor(), ceil() and trunc() for floats
Type: performance Stage: resolved
Components: Interpreter Core Versions: Python 3.9
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: mark.dickinson, serhiy.storchaka
Priority: normal Keywords: patch

Created on 2019-10-30 09:29 by serhiy.storchaka, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 16991 merged serhiy.storchaka, 2019-10-30 09:33
Messages (2)
msg355699 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2019-10-30 09:29
Currently math.floor(), math.ceil() and math.trunc() look up special methods __floor__, __ceil__ and __trunc__ correspondingly and execute them if found. Otherwise they execute common code for floats. There are no special slots for these methods, so looking up these names in type dicts takes some time. It is a waste of time for most common case -- float objects.

The proposed PR adds checks PyFloat_CheckExact() before looking up the special method. Some microbenchmarks:

$ ./python -m pyperf timeit -s "from math import floor" --duplicate 100 "floor(12345.6)"
Before:  Mean +- std dev: 63.2 ns +- 1.7 ns
After:   Mean +- std dev: 51.8 ns +- 1.3 ns

$ ./python -m pyperf timeit -s "from math import ceil" --duplicate 100 "ceil(12345.6)"
Before:  Mean +- std dev: 61.1 ns +- 1.5 ns
After:   Mean +- std dev: 51.9 ns +- 1.1 ns

$ ./python -m pyperf timeit -s "from math import trunc" --duplicate 100 "trunc(12345.6)"
Before:  Mean +- std dev: 72.0 ns +- 1.5 ns
After:   Mean +- std dev: 34.7 ns +- 1.4 ns

We should also check how this optimization affects other types:

$ ./python -m pyperf timeit -s "from math import floor" --duplicate 100 "floor(12345)"
Before:  Mean +- std dev: 56.3 ns +- 1.3 ns
After:   Mean +- std dev: 56.3 ns +- 1.4 ns

$ ./python -m pyperf timeit -s "from math import ceil" --duplicate 100 "ceil(12345)"
Before:  Mean +- std dev: 55.7 ns +- 1.6 ns
After:   Mean +- std dev: 56.8 ns +- 1.6 ns

$ ./python -m pyperf timeit -s "from math import trunc" --duplicate 100 "trunc(12345)"
Before:  Mean +- std dev: 54.7 ns +- 1.3 ns
After:   Mean +- std dev: 56.7 ns +- 1.5 ns
msg356753 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2019-11-16 16:01
New changeset 5fd5cb8d85fab3393dd76c7f3de1cdeb8ecf7203 by Serhiy Storchaka in branch 'master':
bpo-38639: Optimize floor(), ceil() and trunc() for floats. (GH-16991)
https://github.com/python/cpython/commit/5fd5cb8d85fab3393dd76c7f3de1cdeb8ecf7203
History
Date User Action Args
2022-04-11 14:59:22adminsetgithub: 82820
2019-11-16 17:23:10serhiy.storchakasetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2019-11-16 16:01:02serhiy.storchakasetmessages: + msg356753
2019-10-30 09:33:44serhiy.storchakasetkeywords: + patch
stage: patch review
pull_requests: + pull_request16517
2019-10-30 09:30:46serhiy.storchakasettitle: Optimize floor() and ceil() for floats -> Optimize floor(), ceil() and trunc() for floats
2019-10-30 09:29:36serhiy.storchakacreate