Problem
A Python module can call estimate through the generated handle. Each call makes a new Execution object. That procedure uses 8.6 ms. The arithmetic uses 0.001 ms.
A test outside the repository measured 1000 calls of the two-panel estimate.
- Plain Python, 1000 calls. Total 0.0007 s. Mean 0.001 ms per call.
- CSO handle, 1000 calls. Total 8.63 s. Mean 8.63 ms per call.
Execution.__init__. Mean 7.48 ms.
Planner.plan. Mean 3.64 ms.
run() on the same engine after observations.clear(). Mean 0.16 ms.
The same engine gave the correct results for width=2 and then width=1.
Cause
CalculationHandle.__call__ makes a new Execution for each call from ordinary Python. Execution.__init__ reads the source, makes a plan, changes the AST, and compiles the code. The generated binding already keeps one handle for the process.
estimate = load_calculation("../estimate.cso.py", function="estimate", fingerprint="...")
The code is in packages/cso-python/src/cso_python/handles.py.
Recommended change
Keep the Execution object on the handle after the first call.
For the next calls, clear observations and call run() with the new inputs.
Make a new Execution if the set of input names is different from the plan. Make a new Execution if the captured source files changed.
Do not change the public call.
from _cso_bindings.estimate import estimate
result = estimate(width=2)
Do not remove tracing. The default call must continue to record observations.
This change does not decrease the time of python -m cso_python execute. That command starts a new process for each run.
Acceptance
- 1000 calls of the two-panel estimate through the generated handle complete in less than 1 s.
- Results stay the same for
width=2 and width=1.
- If the source files change, the next call uses the new source.
- If the input names change, the next call makes a new plan.
Problem
A Python module can call
estimatethrough the generated handle. Each call makes a newExecutionobject. That procedure uses 8.6 ms. The arithmetic uses 0.001 ms.A test outside the repository measured 1000 calls of the two-panel estimate.
Execution.__init__. Mean 7.48 ms.Planner.plan. Mean 3.64 ms.run()on the same engine afterobservations.clear(). Mean 0.16 ms.The same engine gave the correct results for
width=2and thenwidth=1.Cause
CalculationHandle.__call__makes a newExecutionfor each call from ordinary Python.Execution.__init__reads the source, makes a plan, changes the AST, and compiles the code. The generated binding already keeps one handle for the process.The code is in
packages/cso-python/src/cso_python/handles.py.Recommended change
Keep the
Executionobject on the handle after the first call.For the next calls, clear
observationsand callrun()with the new inputs.Make a new
Executionif the set of input names is different from the plan. Make a newExecutionif the captured source files changed.Do not change the public call.
Do not remove tracing. The default call must continue to record observations.
This change does not decrease the time of
python -m cso_python execute. That command starts a new process for each run.Acceptance
width=2andwidth=1.