Skip to content

Commit

Permalink
test: ✅ add more detailed benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
olliemath committed Aug 18, 2023
1 parent 9fc6e61 commit fb00026
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 13 deletions.
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,21 @@ it is a python port of the [chronoutil](https://github.com/olliemath/chronoutil)

Originally urelativedelta was used for speeding up complicated cashflow bucketing
computations (where there are lots of relativedeltas). It's pretty successful.
Shifting 5 million datetime objects by 100 years gives us:
The following ran under **CPython 3.11**:

| interpreter | urelativedelta | python-dateutil | speedup |
| benchmark | urelativedelta | python-dateutil | speedup |
| ------ | ------ | ------ | ------ |
| cpython 3.11 | 6.72s | 20.36s | 3.03x |
| pypy 3.9 | 0.72s | 3.13s | 4.34x |
| shift 5mn dates by 100 years | 6.65s | 20.35s | 3.06x |
| subtract 5mn date pairs | 7.30s | 17.62s | 2.41x |

and these ran under **PyPy 3.9**:

| benchmark | urelativedelta | python-dateutil | speedup |
| ------ | ------ | ------ | ------ |
| shift 5mn dates by 100 years | 0.72s | 3.09s | 4.29x |
| subtract 5mn date pairs | 1.52s | 3.31s | 2.18x |

all of which means that using pypy and switching libraries can buy you a ~30x speed improvement.

## Usage

Expand Down
54 changes: 45 additions & 9 deletions benches/bench.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,62 @@
from __future__ import annotations

import random
import sys
from datetime import datetime, timedelta
from timeit import timeit

from dateutil.relativedelta import relativedelta as du_delta
import dateutil.relativedelta

from urelativedelta import relativedelta
import urelativedelta

klass = sys.argv[1]
random.seed(12345)
KLASS = sys.argv[1]
NUMDATES = 5_000

dates = [datetime(2000, 1, 1) + timedelta(days=n) for n in range(NUMDATES)]
shuffled = list(dates)
random.shuffle(shuffled)

dates = [datetime(2000, 1, 1) + timedelta(days=n) for n in range(5_000)]

def do_combined():
if KLASS == "urelativedelta":
for d in dates:
d + urelativedelta.relativedelta(years=100)
if KLASS == "dateutil":
for d in dates:
d + dateutil.relativedelta.relativedelta(years=100)


def do_shifts():
if klass == "relativedelta":
if KLASS == "urelativedelta":
delta = urelativedelta.relativedelta(years=100)
for d in dates:
d + relativedelta(years=100)
if klass == "dateutil":
d + delta
if KLASS == "dateutil":
delta = dateutil.relativedelta.relativedelta(years=100)
for d in dates:
d + du_delta(years=100)
d + delta


def do_inits():
if KLASS == "urelativedelta":
for _ in range(NUMDATES):
urelativedelta.relativedelta(years=10, months=10, days=10)
if KLASS == "dateutil":
for _ in range(NUMDATES):
dateutil.relativedelta.relativedelta(years=10, months=10, days=10)


def do_difference_inits():
if KLASS == "urelativedelta":
for d1, d2 in zip(shuffled, shuffled, strict=False):
urelativedelta.relativedelta.difference(d1, d2)
if KLASS == "dateutil":
for d1, d2 in zip(shuffled, shuffled, strict=False):
dateutil.relativedelta.relativedelta(d1, d2)


print(klass, timeit(do_shifts, number=1000))
print(f"{KLASS} combined:", timeit(do_combined, number=1000))
print(f"{KLASS} shifts:", timeit(do_shifts, number=1000))
print(f"{KLASS} inits:", timeit(do_inits, number=1000))
print(f"{KLASS} differences:", timeit(do_difference_inits, number=1000))

0 comments on commit fb00026

Please sign in to comment.