GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — gh-130167: Improve speed of `_pydecimal._all_zeros` and `_pydecimal._exact_half` by replacing `re` by Marius-Juston · Pull Request #132065 · python/cpython Conversation
|
| Benchmark | regex_decimal | non_regex_ends_fast_decimal |
|---|---|---|
| exact | 230 ns | 83.5 ns: 2.76x faster |
| No zeros 1 | 199 ns | 83.9 ns: 2.38x faster |
| No zeros 10 | 207 ns | 84.1 ns: 2.46x faster |
| No zeros 100 | 206 ns | 86.4 ns: 2.38x faster |
| No zeros 1000 | 201 ns | 94.1 ns: 2.13x faster |
| Mixed 1 | 204 ns | 169 ns: 1.21x faster |
| Mixed 10 | 200 ns | 170 ns: 1.18x faster |
| Mixed 100 | 208 ns | 175 ns: 1.19x faster |
| Mixed 1000 | 198 ns | 231 ns: 1.17x slower |
| Zero 1 | 231 ns | 150 ns: 1.54x faster |
| Zero 10 | 237 ns | 180 ns: 1.32x faster |
| Zero 100 | 287 ns | 185 ns: 1.55x faster |
| Zero 1000 | 783 ns | 245 ns: 3.20x faster |
| Geometric mean | (ref) | 1.72x faster |
Benchmark for exact half
| Benchmark | half_regex | half_non_regex_correct |
|---|---|---|
| exact | 176 ns | 97.1 ns: 1.81x faster |
| No half 1 | 178 ns | 124 ns: 1.44x faster |
| No half 10 | 177 ns | 125 ns: 1.42x faster |
| No half 100 | 177 ns | 125 ns: 1.42x faster |
| No half 1000 | 180 ns | 126 ns: 1.42x faster |
| Mixed 1 | 177 ns | 126 ns: 1.41x faster |
| Mixed 10 | 177 ns | 124 ns: 1.42x faster |
| Mixed 100 | 178 ns | 125 ns: 1.42x faster |
| Mixed 1000 | 177 ns | 127 ns: 1.39x faster |
| Half 1 | 232 ns | 230 ns: 1.01x faster |
| Half 10 | 235 ns | 269 ns: 1.14x slower |
| Half 100 | 288 ns | 268 ns: 1.08x faster |
| Half 1000 | 780 ns | 338 ns: 2.31x faster |
| Geometric mean | (ref) | 1.38x faster |
The tests benchmarks
import pyperf def setup_tests_zero(): names = [ ('exact', Decimal('3.5')._int) ] for i in [1, 10, 100, 1000]: names.append((f'No zeros {i}', Decimal('3.1' + '12' * i)._int)) for i in [1, 10, 100, 1000]: names.append((f'Mixed {i}', Decimal('3.12' + '0' * i)._int)) for i in [1, 10, 100, 1000]: names.append((f'Zero {i}', Decimal('3.1' + '0' * i)._int)) return names def setup_tests_half(): names = [ ('exact', Decimal('3.5')._int) ] for i in [1, 10, 100, 1000]: names.append((f'No half {i}', Decimal('3.1' + '12' * i)._int)) for i in [1, 10, 100, 1000]: names.append((f'Mixed {i}', Decimal('3.5' + '0' * i)._int)) for i in [1, 10, 100, 1000]: names.append((f'Half {i}', Decimal('3.15' + '0' * i)._int)) return names method = '' benchmark_method = 'half' benchmark = setup_tests_half if benchmark_method == 'half' else set func = _round_down if method == 'regex' else _is_all_zeros runner = pyperf.Runner() for n, v in benchmark(): # print(func(v)) runner.bench_func(n, func, v)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
I have some doubts this is worthwhile. The |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| _all_zeros = re.compile('0*$').match | ||
| _exact_half = re.compile('50*$').match | ||
| # Checks for regex 0*$ | ||
| def _all_zeros(d_int,prec=0): |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Do we need the prec argument?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
yes we need it, since when it gets called in:
def _round_down(self, prec): """Also known as round-towards-0, truncate.""" if _all_zeros(self._int, prec): return 0 else: return -1
and
def _round_half_up(self, prec): """Rounds 5 up (away from 0)""" if self._int[prec] in '56789': return 1 elif _all_zeros(self._int, prec): return 0 else: return -1
they both need the argument
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Co-authored-by: Pieter Eendebak <[email protected]>
Co-authored-by: Pieter Eendebak <[email protected]>
with the new while loop ( should have done this method first lol ) |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
With the new while loop method for the |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
This is probably not a bottleneck in actual computation ( it's a nice and easy optimization for sure ) and i was planning to use public methods later for benchmarking ( separating them this way though made it simpler to optimize individually ). And yeah I was planning to do larger numbers as well to test this out with repeating patterns as well to see. ( though since the prec sets the initial location of the Though these addition benchmarks will take me some time to do since I will be very busy, so if you wanted to test it yourself feel free! |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
I don't think this change needs to be done. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
If so, hardly it's a "nice optimization". E.g. the re dependency is not removed. BTW, what's you use case for the pure-Python decimal module? In most cases, people will just use C-coded extension. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Fair enough, I don't actually have a use case for the _pydecimal I was just looking through files and functions to see if there was anything that interested me |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.