Skip to content

feat(callable): add CachedCallable for cached function resolution#700

Draft
ptondereau wants to merge 1 commit intomasterfrom
refactor/callable-cache
Draft

feat(callable): add CachedCallable for cached function resolution#700
ptondereau wants to merge 1 commit intomasterfrom
refactor/callable-cache

Conversation

@ptondereau
Copy link
Copy Markdown
Member

Adds the CachedCallable type that caches zend_fcall_info_cache for repeated PHP function calls from Rust, skipping expensive string lookups and hash table searches on subsequent invocations.

  • ZendCallable::cache() resolves once via zend_is_callable_ex
  • CachedCallable::try_call{,_with_named,_named} calls via cached fcc
  • CachedCallableError enum with typed recovery (exceptions recoverable, engine failure poisons)

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 27, 2026

🐰 Bencher Report

Branchrefactor/callable-cache
TestbedPHP 8.4.19 (cli) (built: Mar 13 2026 01:28:58) (NTS)

⚠️ WARNING: No Threshold found!

Without a Threshold, no Alerts will ever be generated.

Click here to create a new Threshold
For more information, see the Threshold documentation.
To only post results if a Threshold exists, set the --ci-only-thresholds flag.

Click to view all benchmark results
BenchmarkEstimated Cyclescycles x 1e3InstructionsinstructionsL1 HitshitsLL HitshitsRAM HitshitsTotal read+writereads/writes
binary_bench::cached_callback::cached_callback_calls lots_of_cached_callback_calls:("cached_callback_call.php", 100_000) -> php '-dex...📈 view plot
⚠️ NO THRESHOLD
549,420.93 x 1e3📈 view plot
⚠️ NO THRESHOLD
378,971,815.00📈 view plot
⚠️ NO THRESHOLD
539,903,845.00📈 view plot
⚠️ NO THRESHOLD
1,902,191.00📈 view plot
⚠️ NO THRESHOLD
175.00📈 view plot
⚠️ NO THRESHOLD
541,806,211.00
binary_bench::cached_callback::cached_callback_calls multiple_cached_callback_calls:("cached_callback_call.php", 10) -> php '-dextensi...📈 view plot
⚠️ NO THRESHOLD
67.35 x 1e3📈 view plot
⚠️ NO THRESHOLD
41,545.00📈 view plot
⚠️ NO THRESHOLD
58,951.00📈 view plot
⚠️ NO THRESHOLD
455.00📈 view plot
⚠️ NO THRESHOLD
175.00📈 view plot
⚠️ NO THRESHOLD
59,581.00
binary_bench::cached_callback::cached_callback_calls single_cached_callback_call:("cached_callback_call.php", 1) -> php '-dextensio...📈 view plot
⚠️ NO THRESHOLD
17.77 x 1e3📈 view plot
⚠️ NO THRESHOLD
7,444.00📈 view plot
⚠️ NO THRESHOLD
10,406.00📈 view plot
⚠️ NO THRESHOLD
247.00📈 view plot
⚠️ NO THRESHOLD
175.00📈 view plot
⚠️ NO THRESHOLD
10,828.00
binary_bench::callback::callback_calls lots_of_callback_calls:("callback_call.php", 100_000) -> php '-dextension...📈 view plot
⚠️ NO THRESHOLD
576,626.78 x 1e3📈 view plot
⚠️ NO THRESHOLD
396,475,564.00📈 view plot
⚠️ NO THRESHOLD
566,109,272.00📈 view plot
⚠️ NO THRESHOLD
2,102,305.00📈 view plot
⚠️ NO THRESHOLD
171.00📈 view plot
⚠️ NO THRESHOLD
568,211,748.00
binary_bench::callback::callback_calls multiple_callback_calls:("callback_call.php", 10) -> php '-dextension=/hom...📈 view plot
⚠️ NO THRESHOLD
69.49 x 1e3📈 view plot
⚠️ NO THRESHOLD
42,997.00📈 view plot
⚠️ NO THRESHOLD
61,127.00📈 view plot
⚠️ NO THRESHOLD
475.00📈 view plot
⚠️ NO THRESHOLD
171.00📈 view plot
⚠️ NO THRESHOLD
61,773.00
binary_bench::callback::callback_calls single_callback_call:("callback_call.php", 1) -> php '-dextension=/home...📈 view plot
⚠️ NO THRESHOLD
17.40 x 1e3📈 view plot
⚠️ NO THRESHOLD
7,321.00📈 view plot
⚠️ NO THRESHOLD
10,237.00📈 view plot
⚠️ NO THRESHOLD
236.00📈 view plot
⚠️ NO THRESHOLD
171.00📈 view plot
⚠️ NO THRESHOLD
10,644.00
binary_bench::function::function_calls lots_of_function_calls:("function_call.php", 100_000) -> php '-dextension...📈 view plot
⚠️ NO THRESHOLD
55,201.09 x 1e3📈 view plot
⚠️ NO THRESHOLD
39,200,145.00📈 view plot
⚠️ NO THRESHOLD
55,200,112.00📈 view plot
⚠️ NO THRESHOLD
49.00📈 view plot
⚠️ NO THRESHOLD
21.00📈 view plot
⚠️ NO THRESHOLD
55,200,182.00
binary_bench::function::function_calls multiple_function_calls:("function_call.php", 10) -> php '-dextension=/hom...📈 view plot
⚠️ NO THRESHOLD
6.59 x 1e3📈 view plot
⚠️ NO THRESHOLD
4,065.00📈 view plot
⚠️ NO THRESHOLD
5,638.00📈 view plot
⚠️ NO THRESHOLD
43.00📈 view plot
⚠️ NO THRESHOLD
21.00📈 view plot
⚠️ NO THRESHOLD
5,702.00
binary_bench::function::function_calls single_function_call:("function_call.php", 1) -> php '-dextension=/home...📈 view plot
⚠️ NO THRESHOLD
1.62 x 1e3📈 view plot
⚠️ NO THRESHOLD
537.00📈 view plot
⚠️ NO THRESHOLD
669.00📈 view plot
⚠️ NO THRESHOLD
44.00📈 view plot
⚠️ NO THRESHOLD
21.00📈 view plot
⚠️ NO THRESHOLD
734.00
binary_bench::method::method_calls lots_of_method_calls:("method_call.php", 100_000) -> php '-dextension=/...📈 view plot
⚠️ NO THRESHOLD
61,700.70 x 1e3📈 view plot
⚠️ NO THRESHOLD
44,000,000.00📈 view plot
⚠️ NO THRESHOLD
61,699,953.00📈 view plot
⚠️ NO THRESHOLD
30.00📈 view plot
⚠️ NO THRESHOLD
17.00📈 view plot
⚠️ NO THRESHOLD
61,700,000.00
binary_bench::method::method_calls multiple_method_calls:("method_call.php", 10) -> php '-dextension=/home/...📈 view plot
⚠️ NO THRESHOLD
6.78 x 1e3📈 view plot
⚠️ NO THRESHOLD
4,400.00📈 view plot
⚠️ NO THRESHOLD
6,146.00📈 view plot
⚠️ NO THRESHOLD
7.00📈 view plot
⚠️ NO THRESHOLD
17.00📈 view plot
⚠️ NO THRESHOLD
6,170.00
binary_bench::method::method_calls single_method_call:("method_call.php", 1) -> php '-dextension=/home/r...📈 view plot
⚠️ NO THRESHOLD
1.23 x 1e3📈 view plot
⚠️ NO THRESHOLD
440.00📈 view plot
⚠️ NO THRESHOLD
591.00📈 view plot
⚠️ NO THRESHOLD
9.00📈 view plot
⚠️ NO THRESHOLD
17.00📈 view plot
⚠️ NO THRESHOLD
617.00
binary_bench::static_method::static_method_calls lots_of_static_calls:("static_method_call.php", 100_000) -> php '-dexte...📈 view plot
⚠️ NO THRESHOLD
55,201.03 x 1e3📈 view plot
⚠️ NO THRESHOLD
39,200,145.00📈 view plot
⚠️ NO THRESHOLD
55,200,112.00📈 view plot
⚠️ NO THRESHOLD
51.00📈 view plot
⚠️ NO THRESHOLD
19.00📈 view plot
⚠️ NO THRESHOLD
55,200,182.00
binary_bench::static_method::static_method_calls multiple_static_calls:("static_method_call.php", 10) -> php '-dextension...📈 view plot
⚠️ NO THRESHOLD
6.54 x 1e3📈 view plot
⚠️ NO THRESHOLD
4,065.00📈 view plot
⚠️ NO THRESHOLD
5,636.00📈 view plot
⚠️ NO THRESHOLD
47.00📈 view plot
⚠️ NO THRESHOLD
19.00📈 view plot
⚠️ NO THRESHOLD
5,702.00
binary_bench::static_method::static_method_calls single_static_call:("static_method_call.php", 1) -> php '-dextension=...📈 view plot
⚠️ NO THRESHOLD
1.56 x 1e3📈 view plot
⚠️ NO THRESHOLD
537.00📈 view plot
⚠️ NO THRESHOLD
669.00📈 view plot
⚠️ NO THRESHOLD
46.00📈 view plot
⚠️ NO THRESHOLD
19.00📈 view plot
⚠️ NO THRESHOLD
734.00
🐰 View full continuous benchmarking report in Bencher

@ptondereau ptondereau force-pushed the refactor/callable-cache branch 3 times, most recently from d203f5b to 70352fa Compare March 27, 2026 15:44
Adds `CachedCallable` type that caches `zend_fcall_info_cache` for
repeated PHP function calls from Rust, skipping expensive string
lookups and hash table searches on subsequent invocations.

- `ZendCallable::cache()` resolves once via `zend_is_callable_ex`
- `CachedCallable::try_call{,_with_named,_named}` calls via cached fcc
- `CachedCallableError` enum with typed recovery (exceptions recoverable,
  engine failure poisons)
- C wrappers for `zend_fcc_addref`/`zend_fcc_dtor` (inline, not bindgen-reachable)
- Integration tests, gungraun benchmarks, guide docs
@ptondereau ptondereau force-pushed the refactor/callable-cache branch from 70352fa to 2fc8942 Compare March 27, 2026 15:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant