use serde::{Deserialize, Serialize};
use std::time::Duration;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FormPerformanceMetrics {
pub form_creation_time: Duration,
pub field_operations: u64,
pub validation_operations: u64,
pub submission_operations: u64,
pub total_operations: u64,
pub memory_usage_bytes: u64,
pub avg_field_operation_time: Duration,
pub avg_validation_time: Duration,
pub avg_submission_time: Duration,
pub peak_memory_usage_bytes: u64,
pub re_render_count: u64,
pub total_validation_time: Duration,
pub total_field_operation_time: Duration,
pub total_submission_time: Duration,
}
impl Default for FormPerformanceMetrics {
fn default() -> Self {
Self {
form_creation_time: Duration::ZERO,
field_operations: 0,
validation_operations: 0,
submission_operations: 0,
total_operations: 0,
memory_usage_bytes: 0,
avg_field_operation_time: Duration::ZERO,
avg_validation_time: Duration::ZERO,
avg_submission_time: Duration::ZERO,
peak_memory_usage_bytes: 0,
re_render_count: 0,
total_validation_time: Duration::ZERO,
total_field_operation_time: Duration::ZERO,
total_submission_time: Duration::ZERO,
}
}
}
impl FormPerformanceMetrics {
pub fn new() -> Self {
Self::default()
}
pub fn record_form_creation(&mut self, duration: Duration) {
self.form_creation_time = duration;
}
pub fn record_field_operation(&mut self, duration: Duration) {
self.field_operations += 1;
self.total_field_operation_time += duration;
self.avg_field_operation_time = if self.field_operations > 0 {
Duration::from_nanos(
(self.total_field_operation_time.as_nanos() as u64) / self.field_operations,
)
} else {
Duration::ZERO
};
self.total_operations += 1;
}
pub fn record_validation(&mut self, duration: Duration) {
self.validation_operations += 1;
self.total_validation_time += duration;
self.avg_validation_time = if self.validation_operations > 0 {
Duration::from_nanos(
(self.total_validation_time.as_nanos() as u64) / self.validation_operations,
)
} else {
Duration::ZERO
};
self.total_operations += 1;
}
pub fn record_submission(&mut self, duration: Duration) {
self.submission_operations += 1;
self.total_submission_time += duration;
self.avg_submission_time = if self.submission_operations > 0 {
Duration::from_nanos(
(self.total_submission_time.as_nanos() as u64) / self.submission_operations,
)
} else {
Duration::ZERO
};
self.total_operations += 1;
}
pub fn record_memory_usage(&mut self, bytes: u64) {
self.memory_usage_bytes = bytes;
if bytes > self.peak_memory_usage_bytes {
self.peak_memory_usage_bytes = bytes;
}
}
pub fn record_re_render(&mut self) {
self.re_render_count += 1;
}
pub fn summary(&self) -> String {
format!(
"Form Performance Summary:\n\
- Form Creation: {:?}\n\
- Field Operations: {} (avg: {:?})\n\
- Validations: {} (avg: {:?})\n\
- Submissions: {} (avg: {:?})\n\
- Total Operations: {}\n\
- Memory Usage: {} bytes (peak: {} bytes)\n\
- Re-renders: {}\n\
- Total Field Time: {:?}\n\
- Total Validation Time: {:?}\n\
- Total Submission Time: {:?}",
self.form_creation_time,
self.field_operations,
self.avg_field_operation_time,
self.validation_operations,
self.avg_validation_time,
self.submission_operations,
self.avg_submission_time,
self.total_operations,
self.memory_usage_bytes,
self.peak_memory_usage_bytes,
self.re_render_count,
self.total_field_operation_time,
self.total_validation_time,
self.total_submission_time
)
}
pub fn is_performance_acceptable(&self, thresholds: &PerformanceThresholds) -> bool {
self.form_creation_time <= thresholds.max_form_creation_time
&& self.avg_field_operation_time <= thresholds.max_field_operation_time
&& self.avg_validation_time <= thresholds.max_validation_time
&& self.avg_submission_time <= thresholds.max_submission_time
&& self.memory_usage_bytes <= thresholds.max_memory_usage_bytes
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceThresholds {
pub max_form_creation_time: Duration,
pub max_field_operation_time: Duration,
pub max_validation_time: Duration,
pub max_submission_time: Duration,
pub max_memory_usage_bytes: u64,
}
impl Default for PerformanceThresholds {
fn default() -> Self {
Self {
max_form_creation_time: Duration::from_millis(100),
max_field_operation_time: Duration::from_millis(10),
max_validation_time: Duration::from_millis(50),
max_submission_time: Duration::from_millis(200),
max_memory_usage_bytes: 1024 * 1024, }
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BenchmarkResults {
pub metrics: FormPerformanceMetrics,
pub meets_thresholds: bool,
pub performance_score: f64,
pub recommendations: Vec<String>,
}
impl BenchmarkResults {
pub fn new(metrics: FormPerformanceMetrics, thresholds: &PerformanceThresholds) -> Self {
let meets_thresholds = metrics.is_performance_acceptable(thresholds);
let performance_score = Self::calculate_performance_score(&metrics, thresholds);
let recommendations = Self::generate_recommendations(&metrics, thresholds);
Self {
metrics,
meets_thresholds,
performance_score,
recommendations,
}
}
fn calculate_performance_score(
metrics: &FormPerformanceMetrics,
thresholds: &PerformanceThresholds,
) -> f64 {
let mut score: f64 = 100.0;
if metrics.form_creation_time > thresholds.max_form_creation_time {
score -= 20.0;
}
if metrics.avg_field_operation_time > thresholds.max_field_operation_time {
score -= 15.0;
}
if metrics.avg_validation_time > thresholds.max_validation_time {
score -= 15.0;
}
if metrics.avg_submission_time > thresholds.max_submission_time {
score -= 20.0;
}
if metrics.memory_usage_bytes > thresholds.max_memory_usage_bytes {
score -= 10.0;
}
score.max(0.0_f64)
}
fn generate_recommendations(
metrics: &FormPerformanceMetrics,
thresholds: &PerformanceThresholds,
) -> Vec<String> {
let mut recommendations = Vec::new();
if metrics.form_creation_time > thresholds.max_form_creation_time {
recommendations.push("Form creation is slow. Consider lazy initialization or reducing initial field count.".to_string());
}
if metrics.avg_field_operation_time > thresholds.max_field_operation_time {
recommendations.push(
"Field operations are slow. Consider batching updates or optimizing field access."
.to_string(),
);
}
if metrics.avg_validation_time > thresholds.max_field_operation_time {
recommendations.push(
"Validation is slow. Consider async validation or reducing validation complexity."
.to_string(),
);
}
if metrics.avg_submission_time > thresholds.max_submission_time {
recommendations.push("Form submission is slow. Consider optimizing submission logic or using background processing.".to_string());
}
if metrics.memory_usage_bytes > thresholds.max_memory_usage_bytes {
recommendations.push("Memory usage is high. Consider reducing field count or optimizing data structures.".to_string());
}
if recommendations.is_empty() {
recommendations.push(
"Performance is within acceptable thresholds. No immediate improvements needed."
.to_string(),
);
}
recommendations
}
}