Performance counter
View this sample's code on GitHub
Overview
The canister can query one of the "performance counters", which is a deterministic monotonically increasing integer approximating the amount of work the canister has done. Developers might use this data to profile and optimize the canister performance.
ic0.performance_counter : (counter_type : i32) -> i64
The argument type
decides which performance counter to return:
0 : current execution instruction counter. The number of WebAssembly instructions the canister has executed since the beginning of the current Message execution.
1 : call context instruction counter.
For replicated message execution, it is the number of WebAssembly instructions the canister has executed within the call context of the current Message execution since Call context creation. The counter monotonically increases across all message executions in the call context until the corresponding call context is removed.
For non-replicated message execution, it is the number of WebAssembly instructions the canister has executed within the corresponding
composite_query_helper
in Query call. The counter monotonically increases across the executions of the composite query method and the composite query callbacks until the correspondingcomposite_query_helper
returns (ignoring WebAssembly instructions executed within any further downstream calls ofcomposite_query_helper
).
In the future, ICP might expose more performance counters.
Prerequisites
This example requires an installation of:
- Install the IC SDK.
- Clone the example dapp project:
git clone https://github.com/dfinity/examples
Step 1: Begin by opening a terminal window and navigating into the project's directory
cd examples/rust/performance_counters
Step 2: Start a clean local Internet Computer replica and a web server
dfx stop
dfx start --clean
This terminal will stay blocked, printing log messages, until the Ctrl+C
is pressed or dfx stop
command is run.
Example output:
% dfx stop && dfx start --clean
[...]
Dashboard: http://localhost:63387/_/dashboard
Step 3: Open another terminal window in the same directory
cd examples/rust/performance_counters
Step 4: Compile and deploy performance_counters
canister
dfx deploy
Example output:
% dfx deploy
[...]
Deployed canisters.
URLs:
Backend canister via Candid interface:
performance_counters: http://127.0.0.1/...
Step 5: Call performance_counters
canister for_update
method
dfx canister call performance_counters for_update
Example output:
% dfx canister call performance_counters for_update
(6_618_678 : nat64, 19_886_107 : nat64)
Note, how the current message execution counter (~6M instructions) is much different from the call context counter (~19M instructions).
Step 6: Check the Internet Computer replica terminal window for more details
Example replica log output:
Performance counters for update call: current (0) call context (1)
before the nested call: 6614001 6614201
> inside the 1st nested call: 12425 12625
after the 1st nested call: 6618836 13250387
> inside the 2nd nested call: 12516 12716
after the 2nd nested call: 6618678 19886107
Note, how the current execution instruction counter (0) stays at ~6M instructions after each await point. By contrast, the call context performance counter (1) is monotonically increasing (~6M, ~13M, ~19M instructions).
Also note, that both counters start over for each nested execution (~12K instructions).
Step 7: Repeat the steps above calling for_composite_query
method
dfx canister call performance_counters for_composite_query
Example output:
% dfx canister call performance_counters for_update
(6_621_477 : nat64, 19_893_467 : nat64)
Example replica log output:
Perf. counters for composite query call: current (0) call context (1)
before the nested call: 6614001 6614201
> inside the 1st nested call: 13567 13767
after the 1st nested call: 6623158 13254766
> inside the 2nd nested call: 13567 13767
after the 2nd nested call: 6621477 19893467
Note the same performance counters behavior for composite queries.
Further learning
- Have a look at the locally running dashboard. The URL is at the end of the
dfx start
command:Dashboard: http://localhost/...
- Check out the Candid user interface for
performance_counters
canister. The URL is at the end of thedfx deploy
command:performance_counters: http://127.0.0.1/...
Canister interface
The performance_counters
canisters provide the following interface:
for_update
— return all the performance counters values after two nested update calls.for_composite_query
— return all the performance counters values after two nested composite query calls.
Conclusion
Performance counters is a great tool to optimize canister performance, both for update calls and queries.
Security considerations and best practices
If you base your application on this example, we recommend you familiarize yourself with and adhere to the security best practices for developing on the Internet Computer. This example may not implement all the best practices.