Ordo JIT compilation and performance optimization guide. Includes Schema-aware JIT, TypedContext derive macro, Cranelift compilation, performance tuning...
Ordo's JIT compiler is based on Cranelift, supporting Schema-aware direct memory access with 20-30x performance improvement.
βββββββββββββββββββ
β Expr AST β
ββββββββββ¬βββββββββ
β
ββββββββββΌβββββββββ
β SchemaJITCompilerβ
ββββββββββ¬βββββββββ
β
ββββββββββββββββΌβββββββββββββββ
β β β
ββββββββββΌβββββββββ β ββββββββββΌβββββββββ
β Field Offset β β β Native Code β
β Resolution β β β Generation β
βββββββββββββββββββ β βββββββββββββββββββ
βββββββββΌβββββββββ
β Machine Code β
β ldr d0, [ptr+N]β
ββββββββββββββββββ
use ordo_derive::TypedContext;
#[derive(TypedContext)]
struct UserContext {
age: i64,
balance: f64,
vip_level: i64,
#[typed_context(skip)] // Skip non-numeric fields
name: String,
}
The generated Schema contains field offsets, JIT compiler directly generates memory load instructions.
use ordo_core::expr::jit::{SchemaJITCompiler, SchemaJITEvaluator};
// Create compiler
let mut compiler = SchemaJITCompiler::new()?;
// Compile expression (with Schema)
let schema = UserContext::schema();
let compiled = compiler.compile_with_schema(&expr, &schema)?;
// Execute
let ctx = UserContext { age: 25, balance: 1000.0, vip_level: 3 };
let result = unsafe { compiled.call_typed(&ctx)? };
| Method | Latency | Use Case |
|---|---|---|
| Interpreter | ~1.63 Β΅s | Dynamic rules, development/debugging |
| Bytecode VM | ~200 ns | General purpose |
| Schema JIT | ~50-80 ns | High-frequency execution, fixed Schema |
// Pre-compile expressions when loading rules
let mut ruleset = RuleSet::from_json(json)?;
ruleset.compile()?; // Pre-compile all expressions to bytecode
// Or use one-step loading
let ruleset = RuleSet::from_json_compiled(json)?;
use ordo_core::prelude::*;
let executor = RuleExecutor::new();
// Batch execution (reduces lock contention)
let inputs: Vec<Value> = load_batch();
let results = executor.execute_batch(&ruleset, inputs)?;
use ordo_core::expr::VectorizedEvaluator;
let evaluator = VectorizedEvaluator::new();
let contexts: Vec<Context> = prepare_contexts();
let results = evaluator.eval_batch(&expr, &contexts)?;
Common functions (len, sum, max, min, abs, count, is_null) have inline fast paths, avoiding HashMap lookups.
let mut compiler = SchemaJITCompiler::new()?;
// View compilation statistics
let stats = compiler.stats();
println!("Successful compiles: {}", stats.successful_compiles);
println!("Total code size: {} bytes", stats.total_code_size);
Configure in Cargo.toml:
[dependencies]
ordo-core = { version = "0.2", features = ["jit"] }
# Full features
ordo-core = { version = "0.2", features = ["default"] } # jit + signature + derive
Note: JIT is not available on WASM targets (Cranelift doesn't support wasm32).
--release modelto = truecodegen-units = 1max_depthRUST_LOG=warn or infoRun built-in benchmarks:
# Basic benchmarks
cargo bench --package ordo-core
# JIT comparison tests
cargo bench --package ordo-core --bench jit_comparison_bench
# Schema JIT tests
cargo bench --package ordo-core --bench schema_jit_bench
expression/eval/simple_compare time: [79.234 ns]
expression/eval/function_call time: [211.45 ns]
rule/simple_ruleset time: [1.6312 Β΅s]
jit/schema_aware/numeric time: [52.341 ns]
crates/ordo-core/src/expr/jit/schema_compiler.rs - Schema JIT compilercrates/ordo-core/src/expr/jit/schema_evaluator.rs - JIT evaluatorcrates/ordo-core/src/expr/jit/typed_context.rs - Typed contextcrates/ordo-derive/src/lib.rs - TypedContext derive macrocrates/ordo-core/benches/ - Benchmarks