Skip to main content

jit_loop/
jit_loop.rs

1//! Compare interpreter vs JIT on a tight counting loop (`feature = "jit"`).
2//!
3//! ```text
4//! cargo run --example jit_loop --features jit --release
5//! ```
6
7use std::time::Instant;
8
9use byteflow::{JitConfig, Program, Runtime, RuntimeConfig, Value};
10
11fn loop_chunk(iterations: i32) -> byteflow::Chunk {
12    let mut program = Program::new("jit-loop");
13    program.function("main", 0, |f| {
14        let limit = f.load_int(i64::from(iterations));
15        let counter = f.load_i32(0);
16        f.while_lt(counter, limit, |f| f.add_imm(counter, 1));
17        f.return_(counter);
18    });
19    program.build()
20}
21
22fn run_once(jit: bool) -> Result<(), Box<dyn std::error::Error>> {
23    let chunk = loop_chunk(1_000_000);
24    let rt = Runtime::with_config(
25        chunk,
26        RuntimeConfig {
27            workers: 1,
28            quantum: 50_000_000,
29            jit: JitConfig {
30                enabled: jit,
31                hot_threshold: 1,
32            },
33            ..Default::default()
34        },
35    )?;
36    let start = Instant::now();
37    let outcome = rt.spawn(0, &[])?.join();
38    let snapshot = rt.metrics();
39    rt.shutdown();
40    let elapsed = start.elapsed();
41    match outcome {
42        byteflow::FlowOutcome::Completed(Value::Int(n)) => {
43            println!("jit={jit} result={n} elapsed={elapsed:?} metrics={snapshot}");
44            Ok(())
45        }
46        other => Err(format!("unexpected outcome: {other:?}").into()),
47    }
48}
49
50fn main() {
51    println!("interpreter:");
52    if let Err(e) = run_once(false) {
53        eprintln!("{e}");
54        std::process::exit(1);
55    }
56    println!("jit:");
57    if let Err(e) = run_once(true) {
58        eprintln!("{e}");
59        std::process::exit(1);
60    }
61}