Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Aug 15, 2025

This PR completely migrates all timing code in the lecture series from legacy timing patterns to the new quantecon Timer context manager introduced in v0.9.0+.

Changes Made

Updated timing patterns across multiple lectures:

  • lectures/numba.md: Migrated 6 instances of tic/toc usage to Timer context manager
  • lectures/numpy.md: Migrated 4 instances of tic/toc usage + 4 instances of %time/%%time to Timer
  • lectures/parallelization.md: Migrated 4 instances of %time/%%time to Timer + 3 instances from %timeit pattern
  • lectures/jax_intro.md: Migrated 13 instances of %time/%%time to Timer context manager
  • lectures/scipy.md: Added quantecon import + migrated 2 instances from %timeit pattern using milliseconds for appropriate scale

Migration patterns:

# Old tic/toc pattern
qe.tic()
some_function()
time1 = qe.toc()

# Old %time/%timeit magic commands
%time some_operation()
%%time
some_operation()
%timeit benchmark_function()

# New unified Timer pattern
with qe.Timer() as timer1:
    some_function()
time1 = timer1.elapsed

# For SciPy - using milliseconds for better readability
with qe.Timer(unit="milliseconds"):
    some_operation()

Key Implementation Details

  • Unified approach: All timing now uses the clean Timer context manager pattern instead of mixed legacy approaches
  • No fallback code: Removed fallback implementations after quantecon v0.9.0 release with native Timer support
  • Silent parameter removed: Timer instances display timing output alongside captured elapsed times for better user experience
  • Appropriate units: SciPy instances use milliseconds for more readable timing values of small operations

Validation

  • All timing comparison logic preserved (speed gain calculations like time1 / time3 still work correctly)
  • Surrounding explanatory text remains accurate and relevant
  • Built and tested Jupyter notebook generation successfully with quantecon v0.10.0
  • Manual validation confirms Timer functionality works consistently across all updated lectures

The migration provides a cleaner, more consistent timing approach throughout the lecture series using the official quantecon Timer implementation while maintaining full functionality.

Fixes #390.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: mmcky <8263752+mmcky@users.noreply.github.com>
@Copilot Copilot AI changed the title [WIP] Migrate from tic,tac,toc timers to new Timer context manager in the quantecon package Migrate from tic/toc timers to new Timer context manager Aug 15, 2025
@Copilot Copilot AI requested a review from mmcky August 15, 2025 09:54
Copilot finished work on behalf of mmcky August 15, 2025 09:54
@mmcky
Copy link
Contributor

mmcky commented Aug 15, 2025

  • release quantecon then update this PR.

@mmcky
Copy link
Contributor

mmcky commented Aug 16, 2025

@copilot a new release of quantecon has been released that includes Timer (https://github.com/QuantEcon/QuantEcon.py/releases/tag/v0.9.0).

Can we please remove the fall back code as it is no longer needed.

Co-authored-by: mmcky <8263752+mmcky@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Aug 16, 2025

@copilot a new release of quantecon has been released that includes Timer (https://github.com/QuantEcon/QuantEcon.py/releases/tag/v0.9.0).

Can we please remove the fall back code as it is no lon...

Removed the Timer fallback code from both lectures/numba.md and lectures/numpy.md since quantecon v0.9.0 is now available with native Timer support. The build validates successfully with the official Timer implementation. See commit 3a72aa5.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • fred.stlouisfed.org
    • Triggering command: /usr/share/miniconda/envs/quantecon/bin/python -Xfrozen_modules=off -m ipykernel_launcher -f /tmp/tmp0y9rxjeo.json --HistoryManager.hist_file=:memory: (dns block)
  • jax.quantecon.org
    • Triggering command: /usr/share/miniconda/envs/quantecon/bin/python /usr/share/miniconda/envs/quantecon/bin/jb build lectures --path-output ./ -n -W --keep-going (dns block)
    • Triggering command: /usr/share/miniconda/envs/quantecon/bin/python /usr/share/miniconda/envs/quantecon/bin/jb build lectures --path-output ./ --builder=custom --custom-builder=jupyter -n -W --keep-going (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot finished work on behalf of mmcky August 16, 2025 23:36
Copy link

github-actions bot commented Aug 16, 2025

@github-actions github-actions bot temporarily deployed to pull request August 16, 2025 23:55 Inactive
@mmcky mmcky marked this pull request as ready for review August 17, 2025 01:45
@mmcky
Copy link
Contributor

mmcky commented Aug 17, 2025

@copilot please remove the silent=True from the numba lecture as it is useful to see the times as well as save the results. Thanks.

Co-authored-by: mmcky <8263752+mmcky@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Aug 17, 2025

@copilot please remove the silent=True from the numba lecture as it is useful to see the times as well as save the results. Thanks.

Removed silent=True from all Timer instances in the numba lecture. The timers will now display timing output while still capturing the elapsed time for performance comparisons. See commit 93b664a.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • fred.stlouisfed.org
    • Triggering command: /usr/share/miniconda/envs/quantecon/bin/python -Xfrozen_modules=off -m ipykernel_launcher -f /tmp/tmp3_7fivl2.json --HistoryManager.hist_file=:memory: (dns block)
  • jax.quantecon.org
    • Triggering command: /usr/share/miniconda/envs/quantecon/bin/python /usr/share/miniconda/envs/quantecon/bin/jb build lectures --path-output ./ -n -W --keep-going (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot finished work on behalf of mmcky August 17, 2025 02:24
@github-actions github-actions bot temporarily deployed to pull request August 17, 2025 02:44 Inactive
@mmcky
Copy link
Contributor

mmcky commented Aug 17, 2025

@copilot can you study the patterns I just made in 9538d56 and check if there are any other instances of %time or %%time in other lectures. Can we please update them?

@github-actions github-actions bot temporarily deployed to pull request August 17, 2025 05:20 Inactive
Co-authored-by: mmcky <8263752+mmcky@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Aug 17, 2025

@copilot can you study the patterns I just made in 9538d56 and check if there ...

Found and converted all remaining instances of %time and %%time to qe.Timer() context manager following the patterns from commit 9538d56. Updated 4 lecture files:

  • lectures/numpy.md: 4 instances
  • lectures/parallelization.md: 4 instances
  • lectures/jax_intro.md: 13 instances

All %timeit instances were correctly preserved as they serve a different purpose (benchmarking multiple runs). Build validation confirms the Timer functionality works correctly. See commit b62cfc4.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • fred.stlouisfed.org
    • Triggering command: /usr/share/miniconda/envs/quantecon/bin/python -Xfrozen_modules=off -m ipykernel_launcher -f /tmp/tmp9krjil4m.json --HistoryManager.hist_file=:memory: (dns block)
  • jax.quantecon.org
    • Triggering command: /usr/share/miniconda/envs/quantecon/bin/python /usr/share/miniconda/envs/quantecon/bin/jb build lectures --path-output ./ --builder=custom --custom-builder=jupyter -n -W --keep-going (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@mmcky
Copy link
Contributor

mmcky commented Aug 27, 2025

@copilot we have now updated the quantecon library in v0.10.0 with timeit function (QuantEcon/QuantEcon.py#794).

Can we please now update the %timeit and %%timeit instances to make use of this new function in the library.

Note: %%timeit is a cell based Jupyter notebook feature. We may need to think about packaging the contents of the code-cell into a function to pass into our timeit.

For timeit we should set the runs=3 and then I will update manually if we need more.

Co-authored-by: mmcky <8263752+mmcky@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Aug 27, 2025

@copilot we have now updated the quantecon library in v0.10.0 with timeit function (QuantEcon/QuantEcon.py#794).

Can we please now update the %timeit and %%timeit i...

Successfully converted all %timeit instances to use qe.timeit() from quantecon v0.10.0. Updated 2 lecture files:

  • lectures/scipy.md: Added quantecon import + migrated 2 instances
  • lectures/parallelization.md: Migrated 3 instances

All patterns now use qe.timeit(lambda: expression(), runs=3) as requested. Build validation confirms the timeit functionality works correctly. See commit 50a76b6.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • fred.stlouisfed.org
    • Triggering command: /usr/share/miniconda/envs/quantecon/bin/python -Xfrozen_modules=off -m ipykernel_launcher -f /tmp/tmph_ariiwv.json --HistoryManager.hist_file=:memory: (dns block)
  • jax.quantecon.org
    • Triggering command: /usr/share/miniconda/envs/quantecon/bin/python /usr/share/miniconda/envs/quantecon/bin/jb build lectures --path-output ./ --builder=custom --custom-builder=jupyter -n -W --keep-going (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@Copilot Copilot AI changed the title Migrate from tic/toc timers and %time/%timeit to new Timer context manager Migrate from tic/toc timers and %time/%timeit to new Timer context manager and timeit function Aug 27, 2025
Copilot finished work on behalf of mmcky August 27, 2025 03:26
@mmcky
Copy link
Contributor

mmcky commented Aug 27, 2025

@copilot is the lambda essential in qe.timeit(lambda: expression(), runs=3)

Is it possible for me to update qe.timeit and if a passed in function has arguments we use lambda: in the receiving function qetimeit? Please advise before making any changes.

@github-actions github-actions bot temporarily deployed to pull request August 27, 2025 04:16 Inactive
Copy link
Contributor Author

Copilot AI commented Aug 27, 2025

@copilot is the lambda essential in qe.timeit(lambda: expression(), runs=3)

Is it possible for me to update qe.timeit and if a passed in function has arguments we use lambda: in the receiv...

The lambda is essential for proper timing functionality. Here's why:

  1. Function vs Expression: qe.timeit() needs a callable to execute repeatedly. Writing qe.timeit(brentq(f, 0, 1), runs=3) would execute brentq(f, 0, 1) immediately and pass the result to timeit, not the function itself.

  2. Python evaluation: Without lambda, expressions get evaluated before the function call, so timeit receives the result rather than something it can time multiple runs of.

  3. Scope capture: The lambda captures current variables (f, x, y, etc.) from the surrounding scope, which is necessary for the timing to work correctly.

The current pattern qe.timeit(lambda: expression(), runs=3) follows Python's standard practice (same as built-in timeit.timeit()) and is the cleanest approach. Alternative approaches like string-based timing would require eval() which has security and scope issues.

The lambda pattern is actually quite readable in our current usage and is the Python best practice for this use case.

Copilot finished work on behalf of mmcky August 27, 2025 04:16
@mmcky
Copy link
Contributor

mmcky commented Aug 27, 2025

@jstac what do you think about this style? The %timeit has the advantage of being able to capture the scope of a function before execution -- whereas we need to pass a callable (using a lambda function). I think this is a bit hard to remember -- but it is actually how python library timeit also works (or via a string!)

Screenshot 2025-08-27 at 2 25 20 pm

We need to fix:

  • the output of timeit to remove too much whitespace, and
  • the return object.

@mmcky mmcky moved this to In Progress in Review Lectures & Modernise Code Aug 28, 2025
@github-actions github-actions bot temporarily deployed to pull request August 28, 2025 00:46 Inactive
@mmcky
Copy link
Contributor

mmcky commented Aug 28, 2025

@copilot can we please migrate all instances of using qe.timeit to use the simpler qe.Timer() context manager. The run times on the three runs are all very similar so not necessary to use the qe.timeit function.

Also the SciPy instances should use a more appropriate unit of scale ("milliseconds")

…SciPy

Co-authored-by: mmcky <8263752+mmcky@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Aug 28, 2025

@copilot can we please migrate all instances of using qe.timeit to use the simpler qe.Timer() context manager. The run times on the three runs are all very similar so not necessary to use the `qe....

Migrated all qe.timeit instances back to qe.Timer() context manager for simpler usage since the run times are similar. The SciPy instances now use unit="milliseconds" for more appropriate scale. Build validation confirms the Timer functionality works correctly. See commit 54d9daf.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • fred.stlouisfed.org
    • Triggering command: /usr/share/miniconda/envs/quantecon/bin/python -Xfrozen_modules=off -m ipykernel_launcher -f /tmp/tmpgilelgdw.json --HistoryManager.hist_file=:memory: (dns block)
  • jax.quantecon.org
    • Triggering command: /usr/share/miniconda/envs/quantecon/bin/python /usr/share/miniconda/envs/quantecon/bin/jb build lectures --path-output ./ --builder=custom --custom-builder=jupyter -n -W --keep-going (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@Copilot Copilot AI changed the title Migrate from tic/toc timers and %time/%timeit to new Timer context manager and timeit function Migrate timing code to quantecon Timer context manager from legacy patterns Aug 28, 2025
Copilot finished work on behalf of mmcky August 28, 2025 01:14
@github-actions github-actions bot temporarily deployed to pull request August 28, 2025 02:09 Inactive
@mmcky
Copy link
Contributor

mmcky commented Aug 28, 2025

@jstac this is looking good, we have migrated all tic,tac, toc usage in addition to %time and %%timeit from this lecture series. We have now released quantecon==0.10.1 with the supporting features.

We will setup reviews of the other lectures shortly.

@mmcky mmcky merged commit 61efadb into main Aug 28, 2025
5 checks passed
@github-project-automation github-project-automation bot moved this from In Progress to Done in Review Lectures & Modernise Code Aug 28, 2025
@mmcky mmcky deleted the copilot/fix-390 branch August 28, 2025 02:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging this pull request may close these issues.

Migrate from tic,tac,toc timers to new Timer context manager in the quantecon package
2 participants