amberjs 1.17.0

JavaScript/TypeScript runtime built with Rust and V8
Documentation
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


use crate::code_analyzer::{CodeAnalyzer, CodeComplexity};
use std::collections::{BTreeMap, HashMap};
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::atomic::AtomicU64;
use std::hash::{Hash, Hasher, DefaultHasher};

/// 热路径代码信息
#[derive(Debug, Clone)]
pub struct HotPathInfo {
    /// 代码标识(基于代码哈希或文件路径)
    pub code_id: String,
    /// 执行次数
    pub execution_count: Arc<AtomicUsize>,
    /// 总执行时间(纳秒)
    pub total_time_ns: Arc<AtomicU64>,
    /// 平均执行时间(纳秒)
    pub avg_time_ns: Arc<AtomicU64>,
    /// 首次执行时间
    pub first_execution: Instant,
    /// 最后执行时间
    pub last_execution: Instant,
    /// 代码复杂度
    pub complexity: CodeComplexity,
    /// 是否被标记为热路径
    pub is_hot_path: bool,
    /// 优化建议
    pub optimization_suggestions: Vec<String>,
}
/// 热路径跟踪配置
#[derive(Debug, Clone)]
pub struct HotPathConfig {
    /// 热路径阈值:执行次数超过此值被认为是热路径
    pub hot_path_threshold: usize,
    /// 执行时间阈值(纳秒):超过此值的代码值得优化
    pub time_threshold_ns: u64,
    /// 监控窗口大小(最近N次执行)
    #[allow(dead_code)]
    pub monitoring_window: usize,
    /// 自动优化是否启用
    #[allow(dead_code)]
    pub auto_optimize: bool,
}
impl Default for HotPathConfig {
    fn default() -> Self {
        Self {
            hot_path_threshold: 10,
            time_threshold_ns: 1_000_000, // 1ms
            monitoring_window: 100,
            auto_optimize: false,
        }
    }
}
/// 热路径跟踪统计
#[derive(Debug, Clone, Default)]
pub struct HotPathStats {
    pub total_codes_tracked: usize,
    pub hot_paths_identified: usize,
    pub total_executions: usize,
    pub avg_execution_time_ns: u64,
    pub optimization_applied: usize,
}
/// 热路径跟踪器 - 识别和优化频繁执行的代码路径
pub struct HotPathTracker {
    config: HotPathConfig,
    /// 代码路径跟踪信息
    paths: Arc<std::sync::Mutex<HashMap<String, HotPathInfo>>>,
    /// 全局统计
    stats: Arc<std::sync::Mutex<HotPathStats>>,
}
impl HotPathTracker {
    /// 创建新的热路径跟踪器
    pub fn new(config: HotPathConfig) -> Self {
        Self {
            config,
            paths: Arc::new(Mutex::new(std::sync::Mutex::new(HashMap::new()))
            stats: Arc::new(Mutex::new(std::sync::Mutex::new(HotPathStats::default()))
        }
    }
    /// 创建默认配置的热路径跟踪器
    pub fn new_default() -> Self {
        Self::new(HotPathConfig::default())
    }
    /// 跟踪代码执行
    /// 返回优化建议(如果有)
    pub fn track_execution(
        &self,
        code: &str,
        file_path: Option<&str>,
        execution_time: Duration,
    ) -> Vec<String> {
        // 生成代码ID
        let code_id: _ = self.generate_code_id(code, file_path);
        // 分析代码复杂度
        let complexity: _ = CodeAnalyzer::analyze_complexity(code);
        // 更新或创建跟踪信息
        let mut suggestions = Vec::new();
        {
            let mut paths = self.paths.lock().unwrap();
            let path_info: _ = paths.entry(code_id.clone()).or_insert_with(|| {
                // 更新统计
                {
                    let mut stats = self.stats.lock().unwrap();
                    stats.total_codes_tracked += 1;
                }
                HotPathInfo {
                    code_id: code_id.clone(),
                    execution_count: Arc::new(Mutex::new(AtomicUsize::new(0)))
                    total_time_ns: Arc::new(Mutex::new(AtomicU64::new(0)))
                    avg_time_ns: Arc::new(Mutex::new(AtomicU64::new(0)))
                    first_execution: Instant::now(),
                    last_execution: Instant::now(),
                    complexity,
                    is_hot_path: false,
                    optimization_suggestions: Vec::new(),
                }
            });
            // 更新执行计数
            let count: _ = path_info.execution_count.fetch_add(1, Ordering::SeqCst) + 1;
            // 更新执行时间统计
            let total_time: _ = path_info
                .total_time_ns
                .fetch_add(execution_time.as_nanos() as u64, Ordering::SeqCst)
                + execution_time.as_nanos() as u64;
            let avg_time: _ = total_time / count as u64;
            path_info.avg_time_ns.store(avg_time, Ordering::SeqCst);
            // 更新最后执行时间
            path_info.last_execution = Instant::now();
            // 检查是否成为热路径
            let was_hot: _ = path_info.is_hot_path;
            let should_be_hot =
                self.should_mark_as_hot_path(count, execution_time, &path_info.complexity);
            if should_be_hot && !was_hot {
                path_info.is_hot_path = true;
                // 更新统计
                {
                    let mut stats = self.stats.lock().unwrap();
                    stats.hot_paths_identified += 1;
                }
                // 生成优化建议
                suggestions = self.generate_optimization_suggestions(path_info);
                path_info.optimization_suggestions = suggestions.clone();
            }
            // 更新全局统计
            {
                let mut stats = self.stats.lock().unwrap();
                stats.total_executions += 1;
                stats.avg_execution_time_ns = (stats.avg_execution_time_ns
                    * (stats.total_executions - 1) as u64
                    + execution_time.as_nanos() as u64)
                    / stats.total_executions as u64;
            }
        }
        suggestions
    }
    /// 获取热路径信息
    pub fn get_hot_paths(&self) -> Vec<HotPathInfo> {
        let paths: _ = self.paths.lock().unwrap();
        paths
            .values()
            .filter(|info| info.is_hot_path)
            .cloned()
            .collect()
    }
    /// 获取特定代码的跟踪信息
    #[allow(dead_code)]
    pub fn get_code_info(&self, code_id: &str) -> Option<HotPathInfo> {
        let paths: _ = self.paths.lock().unwrap();
        paths.get(code_id).cloned()
    }
    /// 获取统计信息
    pub fn get_stats(&self) -> HotPathStats {
        self.stats.lock().unwrap().clone()
    }
    /// 检查是否应该标记为热路径
    fn should_mark_as_hot_path(
        &self,
        execution_count: usize,
        execution_time: Duration,
        complexity: &CodeComplexity,
    ) -> bool {
        // 条件1:执行次数超过阈值
        if execution_count >= self.config.hot_path_threshold {
            return true;
        }
        // 条件2:执行时间超过阈值且代码复杂
        if execution_time.as_nanos() as u64 >= self.config.time_threshold_ns
            && complexity.complexity_score > 10.0
        {
            return true;
        }
        // 条件3:中等到高复杂度代码(超过20分)且执行超过3次
        if complexity.complexity_score > 20.0 && execution_count >= 3 {
            return true;
        }
        // 条件4:非常高复杂度代码(超过50分)且执行超过2次
        if complexity.complexity_score > 50.0 && execution_count >= 2 {
            return true;
        }
        false
    }
    /// 生成优化建议
    fn generate_optimization_suggestions(&self, info: &HotPathInfo) -> Vec<String> {
        let mut suggestions = Vec::new();
        // 基于执行次数的建议
        let count: _ = info.execution_count.load(Ordering::SeqCst);
        if count > 100 {
            suggestions.push("考虑将代码编译为字节码缓存".to_string());
        }
        // 基于执行时间的建议
        let avg_time: _ = info.avg_time_ns.load(Ordering::SeqCst);
        if avg_time > 5_000_000 {
            // 5ms
            suggestions.push("执行时间较长,建议优化算法或数据结构".to_string());
        }
        // 基于复杂度的建议
        if info.complexity.function_count > 5 {
            suggestions.push("函数数量较多,考虑拆分或内联".to_string());
        }
        if info.complexity.loop_count > 3 {
            suggestions.push("循环嵌套较深,考虑循环展开或并行化".to_string());
        }
        if info.complexity.complexity_score > 80.0 {
            suggestions.push("代码复杂度高,建议重构或使用更高效的算法".to_string());
        }
        // 基于代码大小的建议
        if info.complexity.line_count > 50 {
            suggestions.push("代码较长,考虑模块化或拆分".to_string());
        }
        if suggestions.is_empty() {
            suggestions.push("代码执行频繁,可能受益于JIT优化".to_string());
        }
        suggestions
    }
    /// 生成代码ID
    fn generate_code_id(&self, code: &str, file_path: Option<&str>) -> String {
        let mut hasher = DefaultHasher::new();
        // 如果有文件路径,使用路径作为ID
        if let Some(path) = file_path {
            path.hash(&mut hasher);
        } else {
            // 否则使用代码哈希
            code.hash(&mut hasher);
        }
        format!("hot_path_{:x}", hasher.finish())
    }
    /// 清除过期或低频的跟踪数据
    #[allow(dead_code)]
    pub fn cleanup(&self, max_age: Duration, min_executions: usize) {
        let mut paths = self.paths.lock().unwrap();
        let now: _ = Instant::now();
        let to_remove: Vec<String> = paths
            .iter()
            .filter(|(_, info)| {
                let age: _ = now.duration_since(info.last_execution);
                let executions: _ = info.execution_count.load(Ordering::SeqCst);
                age > max_age || executions < min_executions
            })
            .map(|(id, _)| id.clone())
            .collect();
        for id in to_remove {
            paths.remove(&id);
        }
    }
    /// 重置所有统计数据
    pub fn reset(&self) {
        let mut paths = self.paths.lock().unwrap();
        paths.clear();
        let mut stats = self.stats.lock().unwrap();
        *stats = HotPathStats::default();
    }
}
#[cfg(test)]
mod tests {
    #[test]
    fn test_hot_path_identification() {
        let tracker: _ = HotPathTracker::new_default();
        // 执行简单代码10次
        for _ in 0..10 {
            tracker.track_execution("const x = 1 + 1;", None, Duration::from_millis(1));
        }
        let hot_paths: _ = tracker.get_hot_paths();
        assert!(
            !hot_paths.is_empty(),
            "Should identify hot path after threshold"
        )));
    }
    #[test]
    fn test_complex_code_hot_path() {
        let tracker: _ = HotPathTracker::new_default();
        // 执行复杂代码(应该快速成为热路径)
        let complex_code: _ = r#"
            function fibonacci(n) {
                if (n <= 1) return n;
                for (let i: _ = 2; i <= n; i++) {
                    if (i % 2 === 0) {
                        console.log("even");
                    }
                }
                return fibonacci(n - 1) + fibonacci(n - 2);
            }
            class Calculator {
                constructor() { this.result = 0; }
                add(a, b) { return a + b; }
                subtract(a, b) { return a - b; }
                multiply(a, b) { return a * b; }
                divide(a, b) { return a / b; }
            }
        "#;
        // 先分析复杂度
        let complexity: _ = crate::code_analyzer::CodeAnalyzer::analyze_complexity(complex_code);
        println!(
            "Complex code complexity score: {}",
            complexity.complexity_score
        );
        for _ in 0..5 {
            tracker.track_execution(complex_code, None, Duration::from_millis(2));
        }
        let hot_paths: _ = tracker.get_hot_paths();
        assert!(
            !hot_paths.is_empty(),
            "Complex code should become hot path quickly"
        )));
    }
    #[test]
    fn test_optimization_suggestions() {
        let tracker: _ = HotPathTracker::new_default();
        let complex_code: _ = r#"
            function fibonacci(n) {
                if (n <= 1) return n;
                for (let i: _ = 2; i <= n; i++) {
                    if (i % 2 === 0) {
                        console.log("even");
                    }
                }
                return fibonacci(n - 1) + fibonacci(n - 2);
            }
            class Calculator {
                constructor() { this.result = 0; }
                add(a, b) { return a + b; }
            }
        "#;
        for _ in 0..10 {
            tracker.track_execution(complex_code, None, Duration::from_millis(5));
        }
        let hot_paths: _ = tracker.get_hot_paths();
        assert!(!hot_paths.is_empty());
        let hot_path: _ = &hot_paths[0];
        assert!(!hot_path.optimization_suggestions.is_empty());
        println!(
            "Optimization suggestions: {:?}",
            hot_path.optimization_suggestions
        );
    }
    #[test]
    fn test_code_tracking_with_file_path() {
        let tracker: _ = HotPathTracker::new_default();
        tracker.track_execution(
            "const x = 1;",
            Some("/test/file.js"),
            Duration::from_millis(1),
        );
        tracker.track_execution(
            "const x = 1;",
            Some("/test/file.js"),
            Duration::from_millis(1),
        );
        let info =
            tracker.get_code_info(&tracker.generate_code_id("const x = 1;", Some("/test/file.js"));
        assert!(info.is_some());
        let hot_paths: _ = tracker.get_hot_paths();
        // 执行2次应该超过默认阈值(10次),所以不是热路径
        assert_eq!(hot_paths.len(), 0);
    }
    #[test]
    fn test_cleanup_old_paths() {
        let tracker: _ = HotPathTracker::new_default();
        // 执行一次代码
        tracker.track_execution("const x = 1;", None, Duration::from_millis(1));
        // 清理过期数据
        tracker.cleanup(Duration::from_secs(0), 10);
        let hot_paths: _ = tracker.get_hot_paths();
        // 执行次数少于10次,应该被清理
        assert_eq!(hot_paths.len(), 0);
    }
    #[test]
    fn test_reset_tracker() {
        let tracker: _ = HotPathTracker::new_default();
        tracker.track_execution("const x = 1;", None, Duration::from_millis(1));
        let stats_before: _ = tracker.get_stats();
        assert!(stats_before.total_codes_tracked > 0);
        tracker.reset();
        let stats_after: _ = tracker.get_stats();
        assert_eq!(stats_after.total_codes_tracked, 0);
    }
    #[test]
    fn test_multiple_codes_tracking() {
        let tracker: _ = HotPathTracker::new_default();
        // 执行多个不同的代码
        for i in 0..15 {
            tracker.track_execution(&format!("const x = {};", i), None, Duration::from_millis(1));
        }
        let stats: _ = tracker.get_stats();
        assert_eq!(stats.total_codes_tracked, 15);
        // 再执行其中一个代码15次,使其成为热路径
        for _ in 0..15 {
            tracker.track_execution("const x = 5;", None, Duration::from_millis(1));
        }
        let hot_paths: _ = tracker.get_hot_paths();
        assert_eq!(hot_paths.len(), 1);
    }
}