Skip to content

Instantly share code, notes, and snippets.

@waynemaranga
Last active July 18, 2024 22:58
Show Gist options
  • Save waynemaranga/96aa073984a8394a4c4f2906ad93c8b0 to your computer and use it in GitHub Desktop.
Save waynemaranga/96aa073984a8394a4c4f2906ad93c8b0 to your computer and use it in GitHub Desktop.
concretepropertiestestsuite.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"authorship_tag": "ABX9TyPv3u/oa7OZ0thoYExM5qls",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/waynemaranga/96aa073984a8394a4c4f2906ad93c8b0/concretepropertiestestsuite.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "code",
"source": [
"import pytest\n",
"import time\n",
"import numpy as np\n",
"from numpy import random, ndarray as NdArray, testing\n",
"from dataclasses import dataclass, field\n",
"# from icecream import ic\n",
"\n",
"\n",
"@dataclass(order=True)\n",
"class UltimateBendingResults:\n",
" # bending angle\n",
" # theta: float\n",
"\n",
" # ultimate neutral axis depth\n",
" # d_n: float = 0\n",
" # k_u: float = 0\n",
"\n",
" # resultant actions\n",
" n: float = 0\n",
" m_x: float = 0\n",
" m_y: float = 0\n",
" # m_xy: float = 0\n",
"\n",
" # label\n",
" # label: str | None = field(default=None, compare=False)\n",
"\n",
"\n",
"@dataclass\n",
"class BiaxialBendingResults:\n",
" n: float\n",
" results: list[UltimateBendingResults] = field(default_factory=list)\n",
"\n",
" def get_results_lists(self) -> tuple[list[float], list[float]]:\n",
" # build list of results\n",
" m_x_list = []\n",
" m_y_list = []\n",
"\n",
" for result in self.results:\n",
" m_x_list.append(result.m_x)\n",
" m_y_list.append(result.m_y)\n",
"\n",
" return m_x_list, m_y_list\n",
"\n",
"\n",
"@dataclass\n",
"class NewBiaxialBendingResults:\n",
" n: float\n",
" # results: list[UltimateBendingResults] = field(default_factory=list)\n",
" results: NdArray # swap the list out for an NdArray\n",
"\n",
" @classmethod\n",
" def from_list(\n",
" cls,\n",
" n: float,\n",
" results: list[UltimateBendingResults]\n",
" ):\n",
"\n",
" dtype = [('m_x', float), ('m_y', float)]\n",
" # ... specifies the dtype for both m_x/y\n",
"\n",
" np_results: NdArray = np.array(\n",
" [\n",
" (result_.m_x, result_.m_y)\n",
" for result_ in results\n",
" ], dtype=dtype )\n",
"\n",
" return cls(n, np_results)\n",
"\n",
" def get_results_lists(self) -> tuple[np.ndarray, np.ndarray]:\n",
" return self.results['m_x'], self.results['m_y']\n",
"\n",
"\n",
"def generate_test_data(num_results: int) -> list[UltimateBendingResults]:\n",
" return [UltimateBendingResults(\n",
" m_x=random.rand(), m_y=random.rand()\n",
" # examined operation is extracting the m_x/y from the results, only this is needed\n",
" ) for _ in range(num_results)]\n",
"\n",
"# --- ⏲️\n",
"def time_execution(func, *args, **kwargs) -> tuple:\n",
" start_time = time.time()\n",
" result = func(*args, **kwargs)\n",
" end_time = time.time()\n",
"\n",
" return (result, end_time - start_time)\n",
"\n",
"# --- πŸ§ͺ\n",
"@pytest.mark.parametrize(\"num_results\", [10, 100, 1_000, 10_000, 100_000, 1_000_000])\n",
"def test_get_results_lists(num_results) -> None:\n",
" random.seed(42) # seed set for reproducible test outcome\n",
"\n",
" test_data: list[UltimateBendingResults] = generate_test_data(num_results)\n",
"\n",
" # --- Extract m_x/y from the same random test_data\n",
" original_results = BiaxialBendingResults(n=1_000, results=test_data)\n",
" new_results = NewBiaxialBendingResults.from_list(n=1_000, results=test_data)\n",
"\n",
" # --- Time the execution of both operations\n",
" (original_m_x, original_m_y), original_time = time_execution(original_results.get_results_lists) # Original\n",
" (new_m_x, new_m_y), new_time = time_execution(new_results.get_results_lists) # New cl\n",
"\n",
" # --- Check correctness between operations\n",
" assert len(original_m_x) == len(new_m_x) == num_results # check no. of results\n",
" assert len(original_m_y) == len(new_m_y) == num_results\n",
"\n",
" testing.assert_allclose(original_m_x, new_m_x) # check same values of m_x/y\n",
" testing.assert_allclose(original_m_y, new_m_y)\n",
"\n",
" # --- Calc. speedup\n",
" speedup = original_time / new_time if new_time > 0 else float('inf')\n",
" assert new_time < original_time #\n",
"\n",
" # --- πŸ“ Compare\n",
" print(f\"\\nFor {num_results:,} results:\")\n",
" # print(f\"🐌 Original method: {original_time:.6f} seconds\")\n",
" # print(f\"🐎 New method: {new_time:.6f} seconds\")\n",
" print(f\"🐌 Original method: {original_time:.3e} seconds]\") # using scientific,\n",
" print(f\"🐎 New method: {new_time:.3e} secons]\")\n",
" print(f\"⚑ SPEEDUP: {speedup:.2f}x\")\n",
"\n"
],
"metadata": {
"id": "2Lh85bOymORh"
},
"execution_count": 6,
"outputs": []
},
{
"cell_type": "code",
"source": [
"test_get_results_lists(num_results=555_555)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "RFVemXAk0C2n",
"outputId": "e72640db-d8a7-4b79-f04f-7b6b70a6f25a"
},
"execution_count": 7,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"\n",
"For 555,555 results:\n",
"🐌 Original method: 6.562e-02 seconds]\n",
"🐎 New method: 7.868e-06 secons]\n",
"⚑ SPEEDUP: 8340.21x\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"test_get_results_lists(num_results=555_555)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "ehrcv-KX0D9S",
"outputId": "d8b687f0-28fc-48f1-8435-57472c3e0e50"
},
"execution_count": 8,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"\n",
"For 555,555 results:\n",
"🐌 Original method: 6.380e-02 seconds]\n",
"🐎 New method: 8.345e-06 secons]\n",
"⚑ SPEEDUP: 7645.23x\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"test_get_results_lists(num_results=555_555)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "hGDO-10-0GXJ",
"outputId": "aed86420-cf5e-486b-b4d7-68d0f176656b"
},
"execution_count": 9,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"\n",
"For 555,555 results:\n",
"🐌 Original method: 6.621e-02 seconds]\n",
"🐎 New method: 6.437e-06 secons]\n",
"⚑ SPEEDUP: 10285.78x\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"test_get_results_lists(num_results=555_555)\n"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "tS2lxglx5NNx",
"outputId": "69a67ca9-927d-49b7-c84a-2959fb96eaff"
},
"execution_count": 10,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"\n",
"For 555,555 results:\n",
"🐌 Original method: 5.481e-02 seconds]\n",
"🐎 New method: 9.060e-06 secons]\n",
"⚑ SPEEDUP: 6049.58x\n"
]
}
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment