Skip to content

Instantly share code, notes, and snippets.

@posita
Last active October 11, 2022 17:35
Show Gist options
  • Save posita/0995c6481262fd5e9a5fa46fd3b961ca to your computer and use it in GitHub Desktop.
Save posita/0995c6481262fd5e9a5fa46fd3b961ca to your computer and use it in GitHub Desktop.
perf test for python/cpython#74690
.ipynb_checkpoints/
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "88b76898-b6f4-40d9-9ed6-757f6b513ef6",
"metadata": {},
"source": [
"## Perf exploration for [python/cpython#74690](https://github.com/python/cpython/issues/74690)\n",
"\n",
"[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gist/posita/0995c6481262fd5e9a5fa46fd3b961ca/HEAD?labpath=perf_test.ipynb)\n",
"_[[source](https://gist.github.com/posita/0995c6481262fd5e9a5fa46fd3b961ca)]_\n",
"\n",
"Select ``Run All Cells`` from the ``Run`` menu above."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "dc4903b5-f25e-4fb1-8f3c-4bd3d1744373",
"metadata": {},
"outputs": [],
"source": [
"# Install additional requirements if necessary\n",
"import warnings\n",
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"ignore\")\n",
" try:\n",
" import numerary\n",
" except (ImportError, ModuleNotFoundError):\n",
" requirements = [\"numerary~=0.4.2\"]\n",
" try:\n",
" import piplite ; await piplite.install(requirements)\n",
" except ImportError:\n",
" import pip ; pip.main([\"install\"] + requirements)\n",
" import numerary"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "a303393b-70ff-4cf3-ae9f-eb73cdc9f903",
"metadata": {},
"outputs": [],
"source": [
"from abc import abstractproperty\n",
"from decimal import Decimal\n",
"from fractions import Fraction\n",
"from typing import (\n",
" Any,\n",
" Protocol,\n",
" SupportsAbs,\n",
" SupportsComplex,\n",
" SupportsFloat,\n",
" SupportsRound,\n",
" runtime_checkable,\n",
")\n",
"from numerary.types import ( # \"raw\" (non-caching) versions\n",
" _SupportsComplexOps,\n",
" _SupportsConjugate,\n",
" _SupportsDivmod,\n",
" _SupportsFloorCeil,\n",
" _SupportsRealImag,\n",
" _SupportsRealOps,\n",
" _SupportsTrunc,\n",
")\n",
"\n",
"@runtime_checkable\n",
"class SupportsLotsOfNumberStuff(\n",
" _SupportsRealOps,\n",
" _SupportsComplexOps,\n",
" _SupportsDivmod,\n",
" _SupportsTrunc,\n",
" _SupportsFloorCeil,\n",
" _SupportsConjugate,\n",
" _SupportsRealImag,\n",
" SupportsAbs,\n",
" SupportsFloat,\n",
" SupportsComplex,\n",
" SupportsRound,\n",
" Protocol,\n",
"):\n",
" __slots__: Any = ()\n",
"\n",
" @abstractproperty\n",
" def numerator(self) -> int:\n",
" pass\n",
"\n",
" @abstractproperty\n",
" def denominator(self) -> int:\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "d684aec8-1853-45b2-a366-878baab57d28",
"metadata": {},
"outputs": [],
"source": [
"from typing import _ProtocolMeta as ProtocolMeta\n",
"\n",
"class ProtocolMetaShortCircuit(ProtocolMeta):\n",
" def __instancecheck__(cls, instance):\n",
" return super(ProtocolMeta, cls).__instancecheck__(instance) or super(\n",
" ProtocolMetaShortCircuit, cls\n",
" ).__instancecheck__(instance)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "b508e8a6-ef2c-47d1-8446-6d7461a4dfcd",
"metadata": {},
"outputs": [],
"source": [
"@runtime_checkable\n",
"class SupportsLotsOfNumberStuffShortCircuit(\n",
" SupportsLotsOfNumberStuff,\n",
" Protocol,\n",
" metaclass=ProtocolMetaShortCircuit,\n",
"): pass\n",
"\n",
"# ABC registration\n",
"assert isinstance(Fraction(), SupportsLotsOfNumberStuffShortCircuit)\n",
"SupportsLotsOfNumberStuffShortCircuit.register(Fraction)\n",
"\n",
"# Direct derivation\n",
"class FractionShortCircuit(Fraction, SupportsLotsOfNumberStuffShortCircuit): pass"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "598ff85f-2d27-4114-a51a-a83b3feedda1",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"====\n",
"%timeit isinstance(1, SupportsLotsOfNumberStuff)\n",
"50 µs ± 616 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n",
"%timeit isinstance(1, SupportsLotsOfNumberStuffShortCircuit)\n",
"54.4 µs ± 785 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n",
"====\n",
"%timeit isinstance(2.0, SupportsLotsOfNumberStuff)\n",
"48.6 µs ± 464 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n",
"%timeit isinstance(2.0, SupportsLotsOfNumberStuffShortCircuit)\n",
"51.3 µs ± 508 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n",
"====\n",
"%timeit isinstance(Decimal('3'), SupportsLotsOfNumberStuff)\n",
"48.3 µs ± 288 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n",
"%timeit isinstance(Decimal('3'), SupportsLotsOfNumberStuffShortCircuit)\n",
"52.1 µs ± 247 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n",
"====\n",
"%timeit isinstance(Fraction(4, 1), SupportsLotsOfNumberStuff)\n",
"52 µs ± 318 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n",
"%timeit isinstance(Fraction(4, 1), SupportsLotsOfNumberStuffShortCircuit)\n",
"26.1 µs ± 271 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n",
"====\n",
"%timeit isinstance(FractionShortCircuit(5, 1), SupportsLotsOfNumberStuff)\n",
"52.7 µs ± 346 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n",
"%timeit isinstance(FractionShortCircuit(5, 1), SupportsLotsOfNumberStuffShortCircuit)\n",
"262 ns ± 3.02 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)\n"
]
}
],
"source": [
"for v, expected in (\n",
" (1, False),\n",
" (2.0, False),\n",
" (Decimal(3), False),\n",
" (Fraction(4), True),\n",
" (FractionShortCircuit(5), True),\n",
"):\n",
" print(\"====\")\n",
"\n",
" actual = isinstance(v, SupportsLotsOfNumberStuff)\n",
" assert actual == expected\n",
" print(f\"%timeit isinstance({v!r}, SupportsLotsOfNumberStuff)\")\n",
" %timeit isinstance(v, SupportsLotsOfNumberStuff)\n",
"\n",
" actual = isinstance(v, SupportsLotsOfNumberStuffShortCircuit)\n",
" assert actual == expected\n",
" print(f\"%timeit isinstance({v!r}, SupportsLotsOfNumberStuffShortCircuit)\")\n",
" %timeit isinstance(v, SupportsLotsOfNumberStuffShortCircuit)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment