use crate::benchmarks::{BenchmarkConfig, BenchmarkFramework, BenchmarkResult, MetricType};
use rusty_v8 as v8;
use std::fs;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::{Duration, Instant};
fn eval_js(isolate: &mut v8::OwnedIsolate, source: &str) {
v8::scope!(let scope, isolate);
let context = v8::Context::new(scope, Default::default());
let scope = &mut v8::ContextScope::new(scope, context);
let code = v8::String::new(scope, source).unwrap();
let script = v8::Script::compile(scope, code, None).unwrap();
let result = script.run(scope).unwrap();
let _ = result.to_string(scope);
}
pub struct JavaScriptCoreBenchmark;
impl JavaScriptCoreBenchmark {
pub fn new() -> Self {
Self
}
pub fn v8_startup_benchmark(&self) -> BenchmarkResult {
let config: _ = BenchmarkConfig {
iterations: 100,
warmup_iterations: 10,
timeout: Some(Duration::from_secs(30)),
save_raw_data: true,
compare_with_baseline: true,
};
let framework: _ = BenchmarkFramework::new(config);
framework.run_benchmark("v8_startup_time", MetricType::StartupTime, || {
let isolate: _ = v8::Isolate::new(v8::CreateParams::default());
drop(isolate); })
}
pub fn v8_execution_benchmark(&self) -> BenchmarkResult {
let config: _ = BenchmarkConfig {
iterations: 1000,
warmup_iterations: 100,
timeout: Some(Duration::from_secs(60)),
save_raw_data: true,
compare_with_baseline: true,
};
let framework: _ = BenchmarkFramework::new(config);
framework.run_benchmark(
"v8_execution_performance",
MetricType::ExecutionTime,
|| {
let mut isolate = v8::Isolate::new(v8::CreateParams::default());
eval_js(&mut isolate, "1 + 1");
},
)
}
pub fn web_api_fetch_benchmark(&self) -> BenchmarkResult {
let config: _ = BenchmarkConfig {
iterations: 100,
warmup_iterations: 10,
timeout: Some(Duration::from_secs(60)),
save_raw_data: true,
compare_with_baseline: true,
};
let framework: _ = BenchmarkFramework::new(config);
framework.run_benchmark(
"web_api_fetch_performance",
MetricType::ExecutionTime,
|| {
let start: _ = Instant::now();
let _: _ = reqwest::blocking::get("http://localhost:3000/health")
.and_then(|resp| resp.text());
let elapsed: _ = start.elapsed();
elapsed.as_nanos() as u64
},
)
}
pub fn websocket_benchmark(&self) -> BenchmarkResult {
let config: _ = BenchmarkConfig {
iterations: 50,
warmup_iterations: 5,
timeout: Some(Duration::from_secs(60)),
save_raw_data: true,
compare_with_baseline: true,
};
let framework: _ = BenchmarkFramework::new(config);
framework.run_benchmark(
"websocket_connection_performance",
MetricType::ExecutionTime,
|| {
std::thread::sleep(Duration::from_millis(10));
"websocket_connected"
},
)
}
pub fn typescript_compilation_benchmark(&self) -> BenchmarkResult {
let config: _ = BenchmarkConfig {
iterations: 50,
warmup_iterations: 5,
timeout: Some(Duration::from_secs(120)),
save_raw_data: true,
compare_with_baseline: true,
};
let framework: _ = BenchmarkFramework::new(config);
framework.run_benchmark(
"typescript_compilation_performance",
MetricType::ExecutionTime,
|| {
let ts_code: _ = r#"
interface User {
id: number;
name: string;
email?: string;
}
class UserManager {
private users: User[] = [];
addUser(user: User): void {
this.users.push(user);
}
getUser(id: number): User | undefined {
return this.users.find(u => u.id === id);
}
}
"#;
std::thread::sleep(Duration::from_millis(5));
ts_code.len()
},
)
}
pub fn module_loading_benchmark(&self) -> BenchmarkResult {
let config: _ = BenchmarkConfig {
iterations: 100,
warmup_iterations: 10,
timeout: Some(Duration::from_secs(60)),
save_raw_data: true,
compare_with_baseline: true,
};
let framework: _ = BenchmarkFramework::new(config);
framework.run_benchmark(
"module_loading_performance",
MetricType::ExecutionTime,
|| {
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push("tests");
path.push("test_modules");
path.push("test_module.js");
if path.exists() {
let _: _ = fs::read_to_string(path);
} else {
std::thread::sleep(Duration::from_millis(1));
}
"module_loaded"
},
)
}
pub fn concurrent_execution_benchmark(&self) -> BenchmarkResult {
let config: _ = BenchmarkConfig {
iterations: 100,
warmup_iterations: 10,
timeout: Some(Duration::from_secs(60)),
save_raw_data: true,
compare_with_baseline: true,
};
let framework: _ = BenchmarkFramework::new(config);
framework.run_benchmark(
"concurrent_execution_performance",
MetricType::ExecutionTime,
|| {
let num_threads: _ = 10;
let results: _ = Arc::new(Mutex::new(Vec::new()));
let mut handles = vec![];
for _ in 0..num_threads {
let results_clone: _ = Arc::clone(&results);
let handle: _ = thread::spawn(move || {
let mut isolate = v8::Isolate::new(v8::CreateParams::default());
eval_js(&mut isolate, "for(let i=0;i<1000;i++){}");
let result: _ =
format!("thread_complete_{:?}", std::thread::current().id());
{
let mut vec = results_clone.lock().unwrap();
vec.push(result);
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
let results: _ = results.lock().unwrap();
results.len()
},
)
}
pub fn run_all_benchmarks(&self) -> Vec<BenchmarkResult> {
vec![
self.v8_startup_benchmark(),
self.v8_execution_benchmark(),
self.typescript_compilation_benchmark(),
self.module_loading_benchmark(),
self.concurrent_execution_benchmark(),
]
}
}
#[cfg(test)]
mod tests {
#[test]
fn test_javascript_core_benchmark_creation() {
crate::initialize_v8().expect("Failed to initialize V8");
let benchmark: _ = JavaScriptCoreBenchmark::new();
assert!(!benchmark.run_all_benchmarks().is_empty());
}
#[test]
fn test_v8_startup_benchmark() {
crate::initialize_v8().expect("Failed to initialize V8");
let benchmark: _ = JavaScriptCoreBenchmark::new();
let result: _ = benchmark.v8_startup_benchmark();
assert_eq!(result.name, "v8_startup_time");
assert_eq!(result.metric_type, MetricType::StartupTime);
assert!(result.iterations > 0);
assert!(result.avg_duration.as_secs_f64() > 0.0);
}
#[test]
fn test_typescript_compilation_benchmark() {
crate::initialize_v8().expect("Failed to initialize V8");
let benchmark: _ = JavaScriptCoreBenchmark::new();
let result: _ = benchmark.typescript_compilation_benchmark();
assert_eq!(result.name, "typescript_compilation_performance");
assert_eq!(result.metric_type, MetricType::ExecutionTime);
assert!(result.iterations > 0);
}
}