use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
use mcp_execution_codegen::progressive::ProgressiveGenerator;
use mcp_execution_core::{ServerId, ToolName};
use mcp_execution_introspector::{ServerCapabilities, ServerInfo, ToolInfo};
use serde_json::json;
use std::hint::black_box;
fn create_simple_tool(index: usize) -> ToolInfo {
ToolInfo {
name: ToolName::new(format!("simple_tool_{index}")),
description: format!("Simple tool {index}"),
input_schema: json!({
"type": "object",
"properties": {
"id": {"type": "string"}
},
"required": ["id"]
}),
output_schema: None,
}
}
fn create_moderate_tool(index: usize) -> ToolInfo {
ToolInfo {
name: ToolName::new(format!("moderate_tool_{index}")),
description: format!("Moderate complexity tool {index}"),
input_schema: json!({
"type": "object",
"properties": {
"id": {"type": "string"},
"name": {"type": "string"},
"count": {"type": "number"},
"active": {"type": "boolean"},
"tags": {
"type": "array",
"items": {"type": "string"}
}
},
"required": ["id", "name"]
}),
output_schema: Some(json!({
"type": "object",
"properties": {
"result": {"type": "string"},
"code": {"type": "number"}
}
})),
}
}
fn create_complex_tool(index: usize) -> ToolInfo {
ToolInfo {
name: ToolName::new(format!("complex_tool_{index}")),
description: format!("Complex nested tool {index}"),
input_schema: json!({
"type": "object",
"properties": {
"id": {"type": "string"},
"metadata": {
"type": "object",
"properties": {
"name": {"type": "string"},
"priority": {"type": "number"},
"tags": {
"type": "array",
"items": {"type": "string"}
},
"attributes": {
"type": "object",
"properties": {
"color": {"type": "string"},
"size": {"type": "number"}
}
}
}
},
"options": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {"type": "string"},
"value": {"type": "string"},
"enabled": {"type": "boolean"}
}
}
},
"config": {
"type": "object",
"properties": {
"timeout": {"type": "number"},
"retries": {"type": "number"},
"fallback": {
"type": "object",
"properties": {
"url": {"type": "string"}
}
}
}
}
},
"required": ["id", "metadata"]
}),
output_schema: Some(json!({
"type": "object",
"properties": {
"success": {"type": "boolean"},
"data": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {"type": "string"}
}
}
}
}
})),
}
}
fn create_server_info(tool_count: usize, tool_creator: fn(usize) -> ToolInfo) -> ServerInfo {
let tools: Vec<_> = (0..tool_count).map(tool_creator).collect();
ServerInfo {
id: ServerId::new(format!("bench-server-{tool_count}")),
name: format!("Benchmark Server (n={tool_count})"),
version: "1.0.0".to_string(),
tools,
capabilities: ServerCapabilities {
supports_tools: true,
supports_resources: false,
supports_prompts: false,
},
}
}
fn bench_full_generation_scaling(c: &mut Criterion) {
let mut group = c.benchmark_group("full_generation_scaling");
for count in [1, 10, 50, 100, 500, 1000] {
let server_info = create_server_info(count, create_moderate_tool);
let generator = ProgressiveGenerator::new().expect("Generator should initialize");
group.throughput(Throughput::Elements(count as u64));
group.bench_with_input(BenchmarkId::from_parameter(count), &count, |b, _count| {
b.iter(|| {
let result = generator.generate(black_box(&server_info));
assert!(result.is_ok());
});
});
}
group.finish();
}
fn bench_schema_complexity(c: &mut Criterion) {
let mut group = c.benchmark_group("schema_complexity");
let tool_count = 50;
let complexities = [
("simple", create_simple_tool as fn(usize) -> ToolInfo),
("moderate", create_moderate_tool),
("complex", create_complex_tool),
];
for (name, tool_creator) in complexities {
let server_info = create_server_info(tool_count, tool_creator);
let generator = ProgressiveGenerator::new().expect("Generator should initialize");
group.throughput(Throughput::Elements(tool_count as u64));
group.bench_with_input(BenchmarkId::from_parameter(name), name, |b, _| {
b.iter(|| {
let result = generator.generate(black_box(&server_info));
assert!(result.is_ok());
});
});
}
group.finish();
}
fn bench_generator_initialization(c: &mut Criterion) {
c.bench_function("generator_initialization", |b| {
b.iter(|| {
let generator = ProgressiveGenerator::new();
assert!(generator.is_ok());
black_box(generator)
});
});
}
fn bench_type_conversion(c: &mut Criterion) {
use mcp_execution_codegen::common::typescript;
let mut group = c.benchmark_group("type_conversion");
let simple_schema = json!({"type": "string"});
group.bench_function("simple_schema", |b| {
b.iter(|| {
let result = typescript::json_schema_to_typescript(black_box(&simple_schema));
black_box(result)
});
});
let complex_schema = json!({
"type": "object",
"properties": {
"name": {"type": "string"},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {"type": "string"},
"value": {"type": "number"}
}
}
}
},
"required": ["name"]
});
group.bench_function("complex_schema", |b| {
b.iter(|| {
let result = typescript::json_schema_to_typescript(black_box(&complex_schema));
black_box(result)
});
});
group.bench_function("property_extraction", |b| {
b.iter(|| {
let result = typescript::extract_properties(black_box(&complex_schema));
black_box(result)
});
});
group.bench_function("snake_to_camel", |b| {
b.iter(|| {
let result = typescript::to_camel_case(black_box("send_message_to_chat_room"));
black_box(result)
});
});
group.finish();
}
fn bench_memory_patterns(c: &mut Criterion) {
let mut group = c.benchmark_group("memory_patterns");
group.sample_size(50);
let server_info = create_server_info(100, create_moderate_tool);
let generator = ProgressiveGenerator::new().expect("Generator should initialize");
group.bench_function("generate_100_tools", |b| {
b.iter(|| {
let generated = generator
.generate(black_box(&server_info))
.expect("Should succeed");
for file in &generated.files {
black_box(&file.path);
black_box(&file.content);
}
});
});
group.finish();
}
criterion_group!(
name = benches;
config = Criterion::default()
.sample_size(100) .measurement_time(std::time::Duration::from_secs(10))
.warm_up_time(std::time::Duration::from_secs(3));
targets =
bench_generator_initialization,
bench_type_conversion,
bench_schema_complexity,
bench_full_generation_scaling,
bench_memory_patterns,
);
criterion_main!(benches);