forked from paiml/rust-mcp-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path32_simd_parsing_performance.rs
More file actions
417 lines (366 loc) Β· 14.3 KB
/
32_simd_parsing_performance.rs
File metadata and controls
417 lines (366 loc) Β· 14.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
//! SIMD Parsing Performance Example
//!
//! PMCP-4006: Demonstrates SIMD optimization for parsing including:
//! - High-performance JSON-RPC parsing with vectorized operations
//! - Accelerated SSE parsing for real-time event streams
//! - Optimized Base64 encoding/decoding with SIMD
//! - Parallel HTTP header parsing with performance metrics
//! - CPU feature detection and runtime optimization
//! - Comprehensive performance benchmarks and comparisons
//!
//! Run with: cargo run --example 32_simd_parsing_performance --features full
use base64::{engine::general_purpose, Engine as _};
use pmcp::shared::simd_parsing::*;
use pmcp::shared::sse_parser::SseParser;
use pmcp::types::jsonrpc::JSONRPCRequest;
use std::time::Instant;
use tracing::{info, Level};
#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
// Initialize logging
tracing_subscriber::fmt().with_max_level(Level::INFO).init();
info!("π Starting SIMD Parsing Performance Example");
// Display CPU features
info!("π Detecting CPU features...");
let simd_parser = SimdJsonParser::new();
let features = simd_parser.get_cpu_features();
info!(" Detected features: {:?}", features);
if features.avx2 {
info!(" β
AVX2 support detected - using 256-bit vectorized operations");
} else if features.sse42 {
info!(" β
SSE4.2 support detected - using 128-bit vectorized operations");
} else {
info!(" β οΈ No SIMD support detected - falling back to optimized scalar operations");
}
// Demonstrate 1: JSON-RPC Parsing Performance
info!("\nπ JSON-RPC Parsing Performance Comparison");
// Generate test data
let test_requests: Vec<String> = (0..10000)
.map(|i| {
format!(
r#"{{"jsonrpc":"2.0","id":{},"method":"performance_test","params":{{"iteration":{},"data":"{}","timestamp":{}}}}}"#,
i,
i,
"x".repeat(50), // Add some bulk to make parsing meaningful
chrono::Utc::now().timestamp_millis()
)
})
.collect();
// SIMD JSON parsing benchmark
info!(" π Running SIMD JSON parsing benchmark...");
let start = Instant::now();
let mut simd_results = Vec::new();
for json in &test_requests {
let result = simd_parser.parse_request(json.as_bytes())?;
simd_results.push(result);
}
let simd_duration = start.elapsed();
let simd_throughput = test_requests.len() as f64 / simd_duration.as_secs_f64();
// Standard JSON parsing benchmark
info!(" π Running standard JSON parsing benchmark...");
let start = Instant::now();
let mut standard_results = Vec::new();
for json in &test_requests {
let result: JSONRPCRequest = serde_json::from_str(json)?;
standard_results.push(result);
}
let standard_duration = start.elapsed();
let standard_throughput = test_requests.len() as f64 / standard_duration.as_secs_f64();
info!(" π JSON-RPC Parsing Results:");
info!(
" SIMD parsing: {:?} ({:.0} docs/sec)",
simd_duration, simd_throughput
);
info!(
" Standard parsing: {:?} ({:.0} docs/sec)",
standard_duration, standard_throughput
);
info!(
" Speedup: {:.2}x",
standard_duration.as_nanos() as f64 / simd_duration.as_nanos() as f64
);
info!(
" Throughput gain: {:.1}%",
(simd_throughput / standard_throughput - 1.0) * 100.0
);
// Display SIMD parsing metrics
let metrics = simd_parser.get_metrics();
info!(" π SIMD Parser Metrics:");
info!(
" Total bytes processed: {}",
metrics.total_bytes_processed
);
info!(
" Documents parsed: {}",
metrics.total_documents_parsed
);
info!(
" Average parse time: {}ns",
metrics.average_parse_time_ns
);
info!(
" Documents per second: {:.0}",
metrics.documents_per_second
);
info!(
" SIMD operations used: {}",
metrics.simd_operations_used
);
info!(
" Fallback operations: {}",
metrics.fallback_operations
);
// Demonstrate 2: Batch Processing Performance
info!("\nπ¦ Batch Processing Performance");
let batch_json = format!("[{}]", test_requests[0..1000].join(","));
// SIMD batch parsing
let start = Instant::now();
let batch_results = simd_parser.parse_batch_requests(batch_json.as_bytes())?;
let batch_duration = start.elapsed();
info!(" π Batch Processing Results:");
info!(
" Batch size: {} documents",
batch_results.len()
);
info!(" Processing time: {:?}", batch_duration);
info!(
" Batch throughput: {:.0} docs/sec",
batch_results.len() as f64 / batch_duration.as_secs_f64()
);
info!(
" Parallel efficiency: {:.1}%",
(batch_results.len() as f64 / batch_duration.as_secs_f64()) / simd_throughput * 100.0
);
// Demonstrate 3: SSE Parsing Performance
info!("\nπ Server-Sent Events Parsing Performance");
let mut simd_sse_parser = SimdSseParser::new();
let mut standard_sse_parser = SseParser::new();
// Generate SSE test data
let sse_events: Vec<String> = (0..5000)
.map(|i| {
format!(
"event: message\nid: {}\ndata: {{\"type\":\"update\",\"id\":{},\"payload\":\"{}\"}}\n\n",
i,
i,
"y".repeat(100)
)
})
.collect();
let sse_stream = sse_events.join("");
// SIMD SSE parsing benchmark
info!(" π Running SIMD SSE parsing benchmark...");
let start = Instant::now();
let simd_sse_results = simd_sse_parser.parse_chunk(sse_stream.as_bytes())?;
let simd_sse_duration = start.elapsed();
// Standard SSE parsing benchmark
info!(" π Running standard SSE parsing benchmark...");
let start = Instant::now();
let standard_sse_results = standard_sse_parser.feed(&sse_stream);
let standard_sse_duration = start.elapsed();
info!(" π SSE Parsing Results:");
info!(
" Events parsed: {} events",
simd_sse_results.len()
);
info!(
" SIMD SSE parsing: {:?} ({:.0} events/sec)",
simd_sse_duration,
simd_sse_results.len() as f64 / simd_sse_duration.as_secs_f64()
);
info!(
" Standard SSE parsing: {:?} ({:.0} events/sec)",
standard_sse_duration,
standard_sse_results.len() as f64 / standard_sse_duration.as_secs_f64()
);
info!(
" SSE speedup: {:.2}x",
standard_sse_duration.as_nanos() as f64 / simd_sse_duration.as_nanos() as f64
);
// Demonstrate 4: Base64 Encoding/Decoding Performance
info!("\nπ Base64 Encoding/Decoding Performance");
let simd_base64 = SimdBase64::new();
// Generate test data of various sizes
let test_sizes = [1024, 10240, 102400, 1024000]; // 1KB, 10KB, 100KB, 1MB
for size in test_sizes.iter() {
let test_data: Vec<u8> = (0..*size).map(|i| (i % 256) as u8).collect();
// SIMD Base64 encoding
let start = Instant::now();
let simd_encoded = simd_base64.encode(&test_data);
let simd_encode_duration = start.elapsed();
// SIMD Base64 decoding
let start = Instant::now();
let simd_decoded = simd_base64.decode(&simd_encoded)?;
let simd_decode_duration = start.elapsed();
// Standard Base64 encoding
let start = Instant::now();
let standard_encoded = general_purpose::STANDARD.encode(&test_data);
let standard_encode_duration = start.elapsed();
// Standard Base64 decoding
let start = Instant::now();
let standard_decoded = general_purpose::STANDARD.decode(&standard_encoded)?;
let standard_decode_duration = start.elapsed();
assert_eq!(simd_decoded, test_data);
assert_eq!(standard_decoded, test_data);
let encode_speedup =
standard_encode_duration.as_nanos() as f64 / simd_encode_duration.as_nanos() as f64;
let decode_speedup =
standard_decode_duration.as_nanos() as f64 / simd_decode_duration.as_nanos() as f64;
info!(" π Base64 Performance ({} bytes):", size);
info!(
" SIMD encode: {:?} ({:.2}x speedup)",
simd_encode_duration, encode_speedup
);
info!(
" SIMD decode: {:?} ({:.2}x speedup)",
simd_decode_duration, decode_speedup
);
info!(
" Throughput: {:.1} MB/s encode, {:.1} MB/s decode",
*size as f64 / simd_encode_duration.as_secs_f64() / 1_000_000.0,
*size as f64 / simd_decode_duration.as_secs_f64() / 1_000_000.0
);
}
// Demonstrate 5: HTTP Header Parsing Performance
info!("\nπ HTTP Header Parsing Performance");
let http_parser = SimdHttpHeaderParser::new();
// Generate test headers
let test_headers: Vec<String> = (0..1000)
.map(|i| {
format!(
"Content-Type: application/json\r\n\
Content-Length: {}\r\n\
Authorization: Bearer token{}\r\n\
X-Request-ID: req-{}\r\n\
X-Custom-Header-{}: custom-value-{}\r\n\
Cache-Control: no-cache, no-store\r\n\
Accept: application/json, text/plain\r\n\
User-Agent: PMCP-Client/1.0\r\n\
Connection: keep-alive\r\n\r\n",
1000 + i,
i,
i,
i,
i
)
})
.collect();
// SIMD HTTP header parsing
info!(" π Running SIMD HTTP header parsing benchmark...");
let start = Instant::now();
let mut simd_header_results = Vec::new();
for headers in &test_headers {
let parsed = http_parser.parse_headers(headers.as_bytes())?;
simd_header_results.push(parsed);
}
let simd_header_duration = start.elapsed();
// Standard HTTP header parsing (simplified)
info!(" π Running standard HTTP header parsing benchmark...");
let start = Instant::now();
let mut standard_header_results = Vec::new();
for headers in &test_headers {
let mut parsed = std::collections::HashMap::new();
for line in headers.lines() {
if let Some(colon_pos) = line.find(':') {
let name = line[..colon_pos].trim().to_lowercase();
let value = line[colon_pos + 1..].trim().to_string();
parsed.insert(name, value);
}
}
standard_header_results.push(parsed);
}
let standard_header_duration = start.elapsed();
info!(" π HTTP Header Parsing Results:");
info!(" Header sets parsed: {}", simd_header_results.len());
info!(
" SIMD parsing: {:?} ({:.0} sets/sec)",
simd_header_duration,
simd_header_results.len() as f64 / simd_header_duration.as_secs_f64()
);
info!(
" Standard parsing: {:?} ({:.0} sets/sec)",
standard_header_duration,
standard_header_results.len() as f64 / standard_header_duration.as_secs_f64()
);
info!(
" Header speedup: {:.2}x",
standard_header_duration.as_nanos() as f64 / simd_header_duration.as_nanos() as f64
);
// Demonstrate 6: Memory Usage and Cache Efficiency
info!("\nπΎ Memory Usage and Cache Efficiency");
let initial_memory = get_memory_usage();
// Process large amount of data to test memory efficiency
let large_requests: Vec<String> = (0..50000)
.map(|i| {
format!(
r#"{{"jsonrpc":"2.0","id":{},"method":"memory_test","params":{{"data":"{}"}}}}"#,
i,
"z".repeat(200)
)
})
.collect();
for chunk in large_requests.chunks(1000) {
for json in chunk {
simd_parser.parse_request(json.as_bytes())?;
}
}
let final_memory = get_memory_usage();
let memory_increase = final_memory.saturating_sub(initial_memory);
info!(" π Memory Usage Analysis:");
info!(" Initial memory: {} KB", initial_memory);
info!(" Final memory: {} KB", final_memory);
info!(" Memory increase: {} KB", memory_increase);
info!(
" Memory per document: {} bytes",
memory_increase * 1024 / large_requests.len()
);
// Final metrics summary
let final_metrics = simd_parser.get_metrics();
info!(" π Final SIMD Parser Metrics:");
info!(
" Total operations: {} documents",
final_metrics.total_documents_parsed
);
info!(
" Total data processed: {} MB",
final_metrics.total_bytes_processed / 1_000_000
);
info!(
" Average throughput: {:.0} docs/sec",
final_metrics.documents_per_second
);
info!(
" SIMD utilization: {:.1}%",
final_metrics.simd_operations_used as f64
/ (final_metrics.simd_operations_used + final_metrics.fallback_operations) as f64
* 100.0
);
info!("\nπ SIMD parsing optimizations demonstrated:");
info!(" β’ JSON-RPC parsing with AVX2/SSE4.2 vectorization");
info!(" β’ Server-Sent Events parsing with SIMD acceleration");
info!(" β’ Base64 encoding/decoding with vectorized operations");
info!(" β’ HTTP header parsing with parallel processing");
info!(" β’ Runtime CPU feature detection and optimization");
info!(" β’ Memory-efficient processing with cache optimization");
info!(" β’ Comprehensive performance metrics and monitoring");
info!(" β’ Batch processing with parallel execution");
info!("π SIMD parsing performance demonstration complete");
Ok(())
}
/// Simple memory usage tracking (Linux-specific)
fn get_memory_usage() -> usize {
#[cfg(target_os = "linux")]
{
use std::fs;
if let Ok(status) = fs::read_to_string("/proc/self/status") {
for line in status.lines() {
if line.starts_with("VmRSS:") {
if let Some(kb_str) = line.split_whitespace().nth(1) {
return kb_str.parse().unwrap_or(0);
}
}
}
}
}
// Fallback for non-Linux systems
0
}