Benchmarking
Benchmark Host and Guest program
Prerequisite
Before you start, please install the latest Nexus zkVM and read how to create a Nexus host project. We strongly recommend you follow that guide first to understand the basic concepts of host and guest programs and how they work with the Nexus zkVM.
This guide demonstrates how to benchmark the performance of Nexus zkVM using a Fibonacci sequence calculation as an example. We’ll analyze both the guest program’s RISC-V cycle count and the host program’s execution time for various Fibonacci sequence lengths.
After running cargo nexus host benchmark
, a new Rust benchmark
project directory is created with the following structure:
The guest program is located in src/guest/src/main.rs
, and the host program is located in src/main.rs
.
Host program
First, we take a look at the host program. In short, our host program will:
-
Compile the guest program to a RISC-V ELF binary.
-
Prove the execution of the guest program with the public input and public output from environment variables.
-
View the print logs from the guest program.
-
Check the exit code of the proved program. If the exit code is
ExitSuccess
, it means the guest program execution completed successfully as we expect it to. -
Test verify the proof, with the public input and public output pair from environment variables.
To benchmark, we will also add a few lines of code to measure the execution time both proving and verifying the execution of the guest program, as well as print out the proof size.
To implement the above, let’s modify the host program src/main.rs
as follows:
Guest program
The guest program in src/guest/src/main.rs
will be a simple Fibonacci program: it receives an public input n
and returns fib(n+1)
as the public output.
The public input is marked as #[cfg_attr(target_arch = "riscv32", nexus_rt::public_input(x))]
, which means when proving the public input will be passed as the guest program variable x
at runtime.
The public output is the return value of the #[nexus_rt::main]
function, which is fib(n+1)
in this case.
Fibonacci Benchmark
The results below were obtained in 2025-02 on a MacBook Air M1 with 16 Gigabytes of RAM.
Profile host execution time
Because we take the public input and output from environment variables, we can use a simple script to run the benchmark with different inputs and outputs. Save this file as bench.sh
, remember to make it executable with chmod +x bench.sh
, and run it with ./bench.sh
.
Next, we put together a table to show the results. Units are in milliseconds.
n-th Fibonacci | Compile (ms) | Prove (ms) | Verify (ms) | Total Time (ms) | Proof size (bytes) |
---|---|---|---|---|---|
0 | 161 | 1592 | 11 | 1764 | 51968 |
1 | 149 | 1522 | 11 | 1684 | 51968 |
2 | 148 | 1514 | 11 | 1675 | 51968 |
3 | 151 | 1538 | 11 | 1701 | 51440 |
5 | 151 | 1477 | 12 | 1641 | 51968 |
8 | 128 | 1465 | 11 | 1606 | 46008 |
13 | 136 | 1454 | 11 | 1602 | 49304 |
21 | 138 | 1440 | 12 | 1591 | 49880 |
34 | 149 | 1551 | 12 | 1713 | 51968 |
55 | 149 | 1422 | 13 | 1584 | 51440 |
89 | 151 | 1432 | 12 | 1596 | 51440 |
144 | 153 | 1427 | 11 | 1593 | 49460 |
233 | 149 | 1434 | 12 | 1596 | 50384 |
377 | 138 | 1417 | 11 | 1567 | 50368 |
610 | 148 | 1453 | 11 | 1613 | 51968 |
987 | 150 | 1510 | 12 | 1673 | 49280 |
1597 | 149 | 1443 | 11 | 1604 | 50384 |
2584 | 146 | 1460 | 13 | 1620 | 50864 |
4181 | 147 | 1449 | 11 | 1610 | 51968 |
6765 | 149 | 1440 | 11 | 1602 | 51968 |
Notice the proving time is indifferent for the first 20 numbers of the Fibonacci sequence. This is likely due to the overhead of setting up zkVM dominating the cost, as the actual Fibonacci computation is not significant yet.
Let’s push further and calculate from the 200th Fibonacci number.
n-th Fibonacci | Compile (ms) | Prove (ms) | Verify (ms) | Total Time (ms) | Proof size (bytes) |
---|---|---|---|---|---|
200 | 156 | 17416 | 189 | 17762 | 58544 |
201 | 154 | 17179 | 183 | 17518 | 59904 |
202 | 152 | 17468 | 183 | 17804 | 59248 |
204 | 158 | 17238 | 181 | 17579 | 59248 |
205 | 151 | 17242 | 184 | 17579 | 57920 |
Now, the proving time is increasing with the size of the Fibonacci sequence as we would expect. Notice, however, that the verification time remains negligible compared to the proving time.
Suggestions for Developers
Based on these benchmark results, here are some key takeaways and suggestions for developers working with Nexus zkVM:
-
Optimize Guest Programs: Focus on minimizing RISC-V cycles in your guest programs. The benchmark clearly shows that the number of RISC-V cycles directly impacts overall proving time, which is the most significant component of total execution time.
-
Consider Algorithmic Efficiency: When working on computationally demanding scenarios, prioritize efficient algorithm design and implementation. The Fibonacci sequence example demonstrates how complexity can quickly escalate proving time.
-
Profile Regularly: Regularly profile your Nexus zkVM projects to identify performance bottlenecks and opportunities for optimization.
Was this page helpful?