Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: speed up requires_package using caching #3705

Merged
merged 25 commits into from
Jan 27, 2025
Merged

Conversation

germa89
Copy link
Collaborator

@germa89 germa89 commented Jan 27, 2025

Description

requires_package is quite slow because of the attempt to import a package and the error handling.
This is the perfect case of using cache wrapper to avoid executing the importing function if the response is already given. I might be able to expand this to other parts of the library.

I do not expect massive performance improvements on the test library, although it is called quite a lot of times.

Issue linked

Close #3706

Checklist

@germa89 germa89 requested a review from a team as a code owner January 27, 2025 13:52
@ansys-reviewer-bot
Copy link
Contributor

Thanks for opening a Pull Request. If you want to perform a review write a comment saying:

@ansys-reviewer-bot review

@github-actions github-actions bot added the enhancement Improve any current implemented feature label Jan 27, 2025
@germa89 germa89 changed the title test: testing-performance 1 feat: speed up requires_package using caching Jan 27, 2025
@github-actions github-actions bot added the new feature Request or proposal for a new feature label Jan 27, 2025
@germa89 germa89 self-assigned this Jan 27, 2025
@germa89
Copy link
Collaborator Author

germa89 commented Jan 27, 2025

Benchmarks:

8.87s v 0.27s - 32.85x improvements.

Using the test attached in this PR.

Pre-changes

(.venv) ➜  pymapdl git:(main) ✗ pytest -k "test_requires_package_speed"
=================================================== test session starts ===================================================
platform darwin -- Python 3.10.11, pytest-8.3.4, pluggy-1.5.0 -- /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/bin/python3.10
-----------------------------------------------------Testing variables-----------------------------------------------------
Session dependent: DEBUG_TESTING (False), ON_CI (True), TESTING_MINIMAL (False), SUPPORT_PLOTTING (True)
OS dependent: ON_LINUX (False), ON_UBUNTU (False), ON_WINDOWS (False), ON_MACOS (True)
MAPDL dependent: ON_LOCAL (False), ON_STUDENT (False), HAS_GRPC (True), HAS_DPF (False), IS_SMP (False)
---------------------------------------------------Environment variables---------------------------------------------------
PYMAPDL_START_INSTANCE ('False'), PYMAPDL_PORT ('50054'), PYMAPDL_DB_PORT ('50055'), DPF_START_SERVER ('false'), 
----------------------------------------------------Pytest configuration---------------------------------------------------
cachedir: .pytest_cache
Using --random-order-bucket=class
Using --random-order-seed=611366

rootdir: /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl
configfile: .pytest.ini
testpaths: tests
plugins: cov-6.0.0, anyio-4.0.0, pyfakefs-5.7.4, repeat-0.9.3, random-order-1.1.1, pytest_pyvista-0.1.9, sphinx-0.6.3, rerunfailures-15.0, timeout-2.3.1, profiling-1.8.1, memprof-0.2.0
collected 3499 items / 3498 deselected / 2 skipped / 1 selected                                                           

tests/test_mapdl.py::test_requires_package_speed PASSED                                                             [100%]WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
I0000 00:00:1737985481.671747  587899 fork_posix.cc:75] Other threads are currently calling into gRPC, skipping fork() handlers
I0000 00:00:1737985481.678242  587899 fork_posix.cc:75] Other threads are currently calling into gRPC, skipping fork() handlers

============================================== memory consumption estimates ===============================================
pymapdl::tests::test_mapdl.py::test_requires_package_speed  - 253.8 MB
Profiling (from /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/prof/combined.prof):
Mon Jan 27 14:44:41 2025    /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/prof/combined.prof

         45027862 function calls (45027494 primitive calls) in 10.346 seconds

   Ordered by: cumulative time
   List reduced from 933 to 20 due to restriction <20>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000   10.346   10.346 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/runner.py:110(pytest_runtest_protocol)
        1    0.000    0.000   10.346   10.346 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/runner.py:118(runtestprotocol)
        3    0.000    0.000   10.346    3.449 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/runner.py:226(call_and_report)
    23/11    0.000    0.000   10.345    0.940 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/pluggy/_hooks.py:498(__call__)
    23/11    0.000    0.000   10.345    0.940 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/pluggy/_manager.py:111(_hookexec)
    23/11    0.000    0.000   10.345    0.940 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/pluggy/_callers.py:53(_multicall)
        3    0.000    0.000   10.344    3.448 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/runner.py:319(from_call)
        3    0.000    0.000   10.344    3.448 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/runner.py:242(<lambda>)
        1    0.000    0.000    8.868    8.868 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/runner.py:163(pytest_runtest_call)
        1    0.000    0.000    8.868    8.868 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/python.py:1625(runtest)
        1    0.000    0.000    8.868    8.868 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/python.py:152(pytest_pyfunc_call)
        1    0.113    0.113    8.868    8.868 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/tests/test_mapdl.py:2817(test_requires_package_speed)
  1000000    0.293    0.000    8.754    0.000 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/src/ansys/mapdl/core/misc.py:431(wrapper)
  1000000    0.298    0.000    8.394    0.000 /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/importlib/__init__.py:108(import_module)
  1000000    0.264    0.000    8.016    0.000 <frozen importlib._bootstrap>:1038(_gcd_import)
1000005/1000004    1.127    0.000    7.592    0.000 <frozen importlib._bootstrap>:1022(_find_and_load)
  1000000    0.368    0.000    2.611    0.000 <frozen importlib._bootstrap>:216(_lock_unlock_module)
  2000005    1.262    0.000    2.409    0.000 <frozen importlib._bootstrap>:179(_get_module_lock)
  1000005    0.266    0.000    2.019    0.000 <frozen importlib._bootstrap>:169(__enter__)
   129/44    0.000    0.000    1.476    0.034 {built-in method builtins.next}


SVG profile created in /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/prof/combined.svg.

================================================== slowest 10 durations ===================================================
8.87s call     tests/test_mapdl.py::test_requires_package_speed
1.45s setup    tests/test_mapdl.py::test_requires_package_speed
0.03s teardown tests/test_mapdl.py::test_requires_package_speed
============================================== PyMAPDL Pytest short summary ===============================================
===================================== 1 passed, 2 skipped, 3498 deselected in 15.80s ================================

Post-changes (improved)

(.venv) ➜  pymapdl git:(test/testing-performance) ✗ pytest -k "test_requires_package_speed"
=================================================== test session starts ===================================================
platform darwin -- Python 3.10.11, pytest-8.3.4, pluggy-1.5.0 -- /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/bin/python3.10
-----------------------------------------------------Testing variables-----------------------------------------------------
Session dependent: DEBUG_TESTING (False), ON_CI (True), TESTING_MINIMAL (False), SUPPORT_PLOTTING (True)
OS dependent: ON_LINUX (False), ON_UBUNTU (False), ON_WINDOWS (False), ON_MACOS (True)
MAPDL dependent: ON_LOCAL (False), ON_STUDENT (False), HAS_GRPC (True), HAS_DPF (False), IS_SMP (False)
---------------------------------------------------Environment variables---------------------------------------------------
PYMAPDL_START_INSTANCE ('False'), PYMAPDL_PORT ('50054'), PYMAPDL_DB_PORT ('50055'), DPF_START_SERVER ('false'), 
----------------------------------------------------Pytest configuration---------------------------------------------------
cachedir: .pytest_cache
Using --random-order-bucket=class
Using --random-order-seed=703814

rootdir: /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl
configfile: .pytest.ini
testpaths: tests
plugins: cov-6.0.0, anyio-4.0.0, pyfakefs-5.7.4, repeat-0.9.3, random-order-1.1.1, pytest_pyvista-0.1.9, sphinx-0.6.3, rerunfailures-15.0, timeout-2.3.1, profiling-1.8.1, memprof-0.2.0
collected 3523 items / 3522 deselected / 2 skipped / 1 selected                                                           

tests/test_mapdl.py::test_requires_package_speed PASSED                                                             [100%]WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
I0000 00:00:1737985723.607571  600298 fork_posix.cc:75] Other threads are currently calling into gRPC, skipping fork() handlers
I0000 00:00:1737985723.616255  600298 fork_posix.cc:75] Other threads are currently calling into gRPC, skipping fork() handlers

Profiling (from /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/prof/combined.prof):
Mon Jan 27 14:48:43 2025    /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/prof/combined.prof

         2027966 function calls (2027598 primitive calls) in 0.739 seconds

   Ordered by: cumulative time
   List reduced from 934 to 20 due to restriction <20>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.739    0.739 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/runner.py:110(pytest_runtest_protocol)
        1    0.000    0.000    0.739    0.739 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/runner.py:118(runtestprotocol)
        3    0.000    0.000    0.739    0.246 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/runner.py:226(call_and_report)
    23/11    0.000    0.000    0.739    0.067 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/pluggy/_hooks.py:498(__call__)
    23/11    0.000    0.000    0.739    0.067 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/pluggy/_manager.py:111(_hookexec)
    23/11    0.000    0.000    0.739    0.067 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/pluggy/_callers.py:53(_multicall)
        3    0.000    0.000    0.738    0.246 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/runner.py:319(from_call)
        3    0.000    0.000    0.738    0.246 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/runner.py:242(<lambda>)
   129/44    0.000    0.000    0.473    0.011 {built-in method builtins.next}
        1    0.000    0.000    0.464    0.464 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/runner.py:158(pytest_runtest_setup)
        1    0.000    0.000    0.464    0.464 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/runner.py:498(setup)
        1    0.000    0.000    0.464    0.464 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/python.py:1629(setup)
        1    0.000    0.000    0.464    0.464 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/fixtures.py:693(_fillfixtures)
      9/4    0.000    0.000    0.464    0.116 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/fixtures.py:510(getfixturevalue)
     14/4    0.000    0.000    0.464    0.116 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/fixtures.py:549(_get_active_fixturedef)
      3/2    0.000    0.000    0.464    0.232 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/fixtures.py:1037(execute)
        3    0.000    0.000    0.463    0.154 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/fixtures.py:1129(pytest_fixture_setup)
        3    0.000    0.000    0.463    0.154 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/.venv/lib/python3.10/site-packages/_pytest/fixtures.py:882(call_fixture_func)
        2    0.000    0.000    0.463    0.232 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/tests/conftest.py:581(mapdl)
        1    0.000    0.000    0.455    0.455 /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/src/ansys/mapdl/core/launcher.py:1020(launch_mapdl)


SVG profile created in /Users/german.ayuso/Other_pymapdls/pymapdl_0/pymapdl/prof/combined.svg.

================================================== slowest 10 durations ===================================================
0.46s setup    tests/test_mapdl.py::test_requires_package_speed
0.27s call     tests/test_mapdl.py::test_requires_package_speed
0.01s teardown tests/test_mapdl.py::test_requires_package_speed
============================================== PyMAPDL Pytest short summary ===============================================
====================================== 1 passed, 2 skipped, 3522 deselected in 1.86s ======================================

Copy link

codecov bot commented Jan 27, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 88.15%. Comparing base (a2f91e6) to head (6d13fe7).
Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3705      +/-   ##
==========================================
+ Coverage   87.88%   88.15%   +0.27%     
==========================================
  Files         187      187              
  Lines       14710    14717       +7     
==========================================
+ Hits        12928    12974      +46     
+ Misses       1782     1743      -39     

@germa89
Copy link
Collaborator Author

germa89 commented Jan 27, 2025

@pyansys-ci-bot LGTM.

Copy link
Contributor

@pyansys-ci-bot pyansys-ci-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Approving this PR because germa89 said so in here 😬

LGTM

@germa89 germa89 merged commit 9d63421 into main Jan 27, 2025
48 of 49 checks passed
@germa89 germa89 deleted the test/testing-performance branch January 27, 2025 16:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improve any current implemented feature new feature Request or proposal for a new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

requires_package is very slow
2 participants