Skip to content

Instantly share code, notes, and snippets.

@moreati
Created June 12, 2023 22:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save moreati/1893473720b7399073e43b2770724d1f to your computer and use it in GitHub Desktop.
Save moreati/1893473720b7399073e43b2770724d1f to your computer and use it in GitHub Desktop.
Python benchmarks of is_leap(year) variations
import datetime
import random
import pyperf
random.seed(42)
YEARS = [random.randint(-400, 399) for _ in range(65536)]
IS_LEAPS = dict(
b4_100_400 = lambda year: year % 4 == 0 and (year % 100 != 0 or year % 400 == 0),
b4_100_400b = lambda year: (year % 4 == 0 and year % 100 != 0) or year % 400 == 0,
b4_400_100 = lambda year: year % 4 == 0 and (year % 400 == 0 or year % 100 != 0),
b100_4_400 = lambda year: (year % 100 != 0 and year % 4 == 0) or year % 400 == 0,
b100_400_4 = lambda year: (year % 100 != 0 or year % 400 == 0) and year % 4 == 0,
b400_4_100 = lambda year: year % 400 == 0 or (year % 4 == 0 and year % 100 != 0),
b400_100_4 = lambda year: year % 400 == 0 or (year % 100 != 0 and year % 4 == 0),
b400_100_4b = lambda year: (year % 400 == 0 or year % 100 != 0) and year % 4 == 0,
b4_25_16 = lambda year: year % 4 == 0 and (year % 25 != 0 or year % 16 == 0),
b4_25_16b = lambda year: (year % 4 == 0 and year % 25 != 0) or year % 16 == 0,
b4_16_25 = lambda year: year % 4 == 0 and (year % 16 == 0 or year % 25 != 0),
b25_4_16 = lambda year: (year % 25 != 0 and year % 4 == 0) or year % 16 == 0,
b25_16_4 = lambda year: (year % 25 != 0 or year % 16 == 0) and year % 4 == 0,
b16_4_25 = lambda year: year % 16 == 0 or (year % 4 == 0 and year % 25 != 0),
b16_25_4 = lambda year: year % 16 == 0 or (year % 25 != 0 and year % 4 == 0),
b16_25_4b = lambda year: (year % 16 == 0 or year % 25 != 0) and year % 4 == 0,
nb4_100_400 = lambda year: (year % 4 == 0) & ((year % 100 != 0) | (year % 400 == 0)),
nb4_100_400b = lambda year: ((year % 4 == 0) & (year % 100 != 0)) | (year % 400 == 0),
nb4_400_100 = lambda year: (year % 4 == 0) & ((year % 400 == 0) | (year % 100 != 0)),
nb100_4_400 = lambda year: ((year % 100 != 0) & (year % 4 == 0)) | (year % 400 == 0),
nb100_400_4 = lambda year: ((year % 100 != 0) | (year % 400 == 0)) & (year % 4 == 0),
nb400_4_100 = lambda year: (year % 400 == 0) | ((year % 4 == 0) & (year % 100 != 0)),
nb400_100_4 = lambda year: (year % 400 == 0) | ((year % 100 != 0) & (year % 4 == 0)),
nb400_100_4b = lambda year: ((year % 400 == 0) | (year % 100 != 0)) & (year % 4 == 0),
nb4_25_16 = lambda year: (year % 4 == 0) & ((year % 25 != 0) | (year % 16 == 0)),
nb4_25_16b = lambda year: ((year % 4 == 0) & (year % 25 != 0)) | (year % 16 == 0),
nb4_16_25 = lambda year: (year % 4 == 0) & ((year % 16 == 0) | (year % 25 != 0)),
nb25_4_16 = lambda year: ((year % 25 != 0) & (year % 4 == 0)) | (year % 16 == 0),
nb25_16_4 = lambda year: ((year % 25 != 0) | (year % 16 == 0)) & (year % 4 == 0),
nb16_4_25 = lambda year: (year % 16 == 0) | ((year % 4 == 0) & (year % 25 != 0)),
nb16_25_4 = lambda year: (year % 16 == 0) | ((year % 25 != 0) & (year % 4 == 0)),
nb16_25_4b = lambda year: ((year % 16 == 0) | (year % 25 != 0)) & (year % 4 == 0),
)
for name, fn in IS_LEAPS.items()
for year in range(-400, 400):
assert fn(year) = datetime._is_leap(year)
runner = pyperf.Runner()
for name, fn in IS_LEAPS.items():
runner.timeit(name, '[fn(year) for year in years]', globals=dict(fn=fn, years=YEARS))
@moreati
Copy link
Author

moreati commented Jun 12, 2023

Ported from https://stackoverflow.com/a/60646967/293340. On CPython 3.11, macOS 13.3.1, Apple M1 Max
the variants b4_25_16 and b4_100_400 are joint first.

$ virtualenv -ppython3 v3 
created virtual environment CPython3.11.3.final.0-64 in 412ms
  creator CPython3Posix(dest=/Users/alex/src/taime/v3, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, wheel=bundle, setuptools=bundle, via=copy, app_data_dir=/Users/alex/Library/Application Support/virtualenv)
    added seed packages: mypy==1.3.0, mypy_extensions==1.0.0, pip==23.0, setuptools==67.1.0, typing_extensions==4.6.2, wheel==0.38.4
  activators NushellActivator,PythonActivator,FishActivator,CShellActivator,PowerShellActivator,BashActivator

$ v3/bin/pip install pyperf 
Collecting pyperf
  Downloading pyperf-2.6.1-py3-none-any.whl (139 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 139.7/139.7 kB 6.1 MB/s eta 0:00:00
Collecting psutil>=5.9.0
  Using cached psutil-5.9.5-cp38-abi3-macosx_11_0_arm64.whl (246 kB)
Installing collected packages: psutil, pyperf
Successfully installed psutil-5.9.5 pyperf-2.6.1

$ v3/bin/python is_leaps.py 
.....................
b4_100_400: Mean +- std dev: 3.49 ms +- 0.02 ms
.....................
b4_100_400b: Mean +- std dev: 4.57 ms +- 0.02 ms
.....................
b4_400_100: Mean +- std dev: 3.88 ms +- 0.02 ms
.....................
b100_4_400: Mean +- std dev: 5.24 ms +- 0.04 ms
.....................
b100_400_4: Mean +- std dev: 4.04 ms +- 0.03 ms
.....................
b400_4_100: Mean +- std dev: 5.20 ms +- 0.03 ms
.....................
b400_100_4: Mean +- std dev: 5.94 ms +- 0.05 ms
.....................
b400_100_4b: Mean +- std dev: 5.73 ms +- 0.03 ms
.....................
b4_25_16: Mean +- std dev: 3.47 ms +- 0.03 ms
.....................
b4_25_16b: Mean +- std dev: 4.15 ms +- 0.05 ms
.....................
b4_16_25: Mean +- std dev: 3.77 ms +- 0.10 ms
.....................
b25_4_16: Mean +- std dev: 4.73 ms +- 0.01 ms
.....................
b25_16_4: Mean +- std dev: 4.05 ms +- 0.02 ms
.....................
b16_4_25: Mean +- std dev: 4.38 ms +- 0.02 ms
.....................
b16_25_4: Mean +- std dev: 5.12 ms +- 0.02 ms
.....................
b16_25_4b: Mean +- std dev: 4.92 ms +- 0.02 ms
.....................
nb4_100_400: Mean +- std dev: 6.35 ms +- 0.03 ms
.....................
nb4_100_400b: Mean +- std dev: 6.36 ms +- 0.04 ms
.....................
nb4_400_100: Mean +- std dev: 6.41 ms +- 0.04 ms
.....................
nb100_4_400: Mean +- std dev: 6.38 ms +- 0.03 ms
.....................
nb100_400_4: Mean +- std dev: 6.35 ms +- 0.03 ms
.....................
nb400_4_100: Mean +- std dev: 6.41 ms +- 0.03 ms
.....................
nb400_100_4: Mean +- std dev: 6.40 ms +- 0.01 ms
.....................
nb400_100_4b: Mean +- std dev: 6.39 ms +- 0.06 ms
.....................
nb4_25_16: Mean +- std dev: 5.77 ms +- 0.02 ms
.....................
nb4_25_16b: Mean +- std dev: 5.78 ms +- 0.02 ms
.....................
nb4_16_25: Mean +- std dev: 5.90 ms +- 0.07 ms
.....................
nb25_4_16: Mean +- std dev: 5.81 ms +- 0.02 ms
.....................
nb25_16_4: Mean +- std dev: 5.74 ms +- 0.02 ms
.....................
nb16_4_25: Mean +- std dev: 5.74 ms +- 0.03 ms
.....................
nb16_25_4: Mean +- std dev: 5.77 ms +- 0.04 ms
.....................
nb16_25_4b: Mean +- std dev: 5.75 ms +- 0.02 ms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment