import hono import time import net.http import regex fn main() { println('=== 深度路由性能分析 ===') // 测试1: 逐步分解第一次匹配的每个步骤 test_step_by_step_breakdown() // 测试2: 分析正则表达式编译开销 test_regex_compilation_overhead() // 测试3: 分析内存分配开销 test_memory_allocation_overhead() // 测试4: 对比不同实现方式 test_implementation_comparison() println('✅ 深度路由性能分析完成') } fn test_step_by_step_breakdown() { println('\n📊 逐步分解第一次匹配...') mut router := hono.ContextHybridRouter.new() route_path := '/api/:version/users/:user_id/posts/:post_id' test_path := '/api/v1/users/123/posts/456' handler := hono.ContextHandler{ path: route_path handler: fn (mut c hono.Context) http.Response { return c.text('test') } } router.add_route('GET', handler, '') router.clear_cache() router.clear_regex_cache() println(' 开始逐步计时...') // 步骤1: 静态路由检查 start_time1 := time.now() static_result := router.match_static_route('GET', test_path) step1_time := time.since(start_time1) println(' 步骤1 - 静态路由检查: ${step1_time}') if static_result != none { println(' ❌ 意外匹配到静态路由') return } // 步骤2: 缓存检查 start_time2 := time.now() cache_key := 'GET:${test_path}' cache_result := router.cache.get(cache_key) step2_time := time.since(start_time2) println(' 步骤2 - 缓存检查: ${step2_time}') if cache_result != none { println(' ❌ 意外命中缓存') return } // 步骤3: 动态路由遍历开始 start_time3 := time.now() // 模拟动态路由匹配的开始部分 mut found_handler_path := '' for handler_item in router.dynamic_routes { if handler_item.path == route_path { found_handler_path = handler_item.path break } } step3_time := time.since(start_time3) println(' 步骤3 - 找到目标路由: ${step3_time}') if found_handler_path == '' { println(' ❌ 未找到目标路由') return } // 步骤4: 正则表达式缓存检查 start_time4 := time.now() cached_regex := router.regex_cache[route_path] step4_time := time.since(start_time4) println(' 步骤4 - 正则缓存检查: ${step4_time}') // 步骤5: 正则表达式编译(如果需要) start_time5 := time.now() // 模拟正则表达式编译过程 mut replaced_path := route_path mut param_names := []string{} // 提取参数名 mut param_reg := regex.regex_opt(r':[a-zA-Z_][a-zA-Z0-9_]*') or { println(' ❌ 参数正则创建失败') return } all_params := param_reg.find_all_str(route_path) for param in all_params { param_names << param[1..] } step5a_time := time.since(start_time5) println(' 步骤5a - 参数提取: ${step5a_time}') // 转义特殊字符 start_time5b := time.now() special_chars := ['?', '+', '.', '(', ')', '[', ']', '{', '}', '^', '$', '|'] for ch in special_chars { replaced_path = replaced_path.replace(ch, '\\${ch}') } step5b_time := time.since(start_time5b) println(' 步骤5b - 字符转义: ${step5b_time}') // 替换参数为捕获组 start_time5c := time.now() replaced_path = param_reg.replace_by_fn(replaced_path, fn (re regex.RE, in_txt string, start int, end int) string { param_name := in_txt[start+1..end] return '(?P<${param_name}>[^/]+)' }) replaced_path = '^${replaced_path}$' step5c_time := time.since(start_time5c) println(' 步骤5c - 参数替换: ${step5c_time}') // 编译最终正则表达式 start_time5d := time.now() mut final_regex := regex.regex_opt(replaced_path) or { println(' ❌ 最终正则编译失败') return } step5d_time := time.since(start_time5d) println(' 步骤5d - 正则编译: ${step5d_time}') // 步骤6: 正则匹配 start_time6 := time.now() match_result := final_regex.matches_string(test_path) step6_time := time.since(start_time6) println(' 步骤6 - 正则匹配: ${step6_time}') if !match_result { println(' ❌ 正则匹配失败') return } // 步骤7: 参数提取 start_time7 := time.now() mut param_map := map[string]string{} for param_name in param_names { group := final_regex.get_group_by_name(test_path, param_name) param_map[param_name] = group } step7_time := time.since(start_time7) println(' 步骤7 - 参数提取: ${step7_time}') // 步骤8: 创建结果对象 start_time8 := time.now() route_match := hono.ContextRouteMatch{ handler: router.dynamic_routes[0] // 使用找到的路由 params: param_map path: found_handler_path base_path: '' } step8_time := time.since(start_time8) println(' 步骤8 - 创建结果: ${step8_time}') // 步骤9: 缓存结果 start_time9 := time.now() router.cache.put(cache_key, route_match) step9_time := time.since(start_time9) println(' 步骤9 - 缓存结果: ${step9_time}') // 计算总时间 total_manual_time := step1_time + step2_time + step3_time + step4_time + step5a_time + step5b_time + step5c_time + step5d_time + step6_time + step7_time + step8_time + step9_time println('\n 手动计算总时间: ${total_manual_time}') // 对比实际的完整匹配时间 router.clear_cache() router.clear_regex_cache() start_time_full := time.now() actual_result := router.match_route('GET', test_path) full_time := time.since(start_time_full) println(' 实际完整匹配时间: ${full_time}') if actual_result != none { println(' ✅ 实际匹配成功') if full_time > total_manual_time { overhead := time.Duration(full_time.nanoseconds() - total_manual_time.nanoseconds()) println(' 🚨 发现隐藏开销: ${overhead}') } else { println(' ✅ 时间基本一致') } } } fn test_regex_compilation_overhead() { println('\n📊 分析正则表达式编译开销...') test_patterns := [ { 'name': '简单模式' 'pattern': '/users/:id' 'regex': '^/users/(?P[^/]+)$' }, { 'name': '中等模式' 'pattern': '/users/:id/posts/:post_id' 'regex': '^/users/(?P[^/]+)/posts/(?P[^/]+)$' }, { 'name': '复杂模式' 'pattern': '/api/:version/users/:user_id/posts/:post_id' 'regex': '^/api/(?P[^/]+)/users/(?P[^/]+)/posts/(?P[^/]+)$' } ] for pattern in test_patterns { println('\n 测试: ${pattern['name']}') println(' 原始模式: ${pattern['pattern']}') println(' 目标正则: ${pattern['regex']}') // 测试直接编译预构建的正则表达式 start_time1 := time.now() mut direct_regex := regex.regex_opt(pattern['regex']) or { println(' ❌ 直接编译失败') continue } direct_time := time.since(start_time1) println(' 直接编译时间: ${direct_time}') // 测试通过路由器编译(包含所有转换步骤) mut router := hono.ContextHybridRouter.new() router.clear_regex_cache() start_time2 := time.now() _, _, _ := router.match_path_with_regex('/dummy/path', pattern['pattern']) router_time := time.since(start_time2) println(' 路由器编译时间: ${router_time}') if router_time > direct_time { overhead := time.Duration(router_time.nanoseconds() - direct_time.nanoseconds()) println(' 转换开销: ${overhead}') } // 测试编译后的匹配性能 test_path := match pattern['name'] { '简单模式' { '/users/123' } '中等模式' { '/users/123/posts/456' } '复杂模式' { '/api/v1/users/123/posts/456' } else { '/test' } } iterations := 10000 start_time3 := time.now() for _ in 0 .. iterations { direct_regex.matches_string(test_path) } direct_match_time := time.since(start_time3) avg_direct_match := f64(direct_match_time.microseconds()) / f64(iterations) if cached_regex := router.regex_cache[pattern['pattern']] { start_time4 := time.now() for _ in 0 .. iterations { cached_regex.regex.matches_string(test_path) } cached_match_time := time.since(start_time4) avg_cached_match := f64(cached_match_time.microseconds()) / f64(iterations) println(' 直接匹配平均: ${avg_direct_match:.3f}μs') println(' 缓存匹配平均: ${avg_cached_match:.3f}μs') } } } fn test_memory_allocation_overhead() { println('\n📊 分析内存分配开销...') // 测试各种数据结构创建的开销 iterations := 10000 // 测试map创建 start_time1 := time.now() for _ in 0 .. iterations { _ := map[string]string{} } map_creation_time := time.since(start_time1) avg_map_creation := f64(map_creation_time.microseconds()) / f64(iterations) println(' 平均map创建: ${avg_map_creation:.3f}μs') // 测试数组创建 start_time2 := time.now() for _ in 0 .. iterations { _ := []string{} } array_creation_time := time.since(start_time2) avg_array_creation := f64(array_creation_time.microseconds()) / f64(iterations) println(' 平均数组创建: ${avg_array_creation:.3f}μs') // 测试结构体创建 start_time3 := time.now() for _ in 0 .. iterations { _ := hono.ContextRouteMatch{ handler: hono.IHandler(unsafe { nil }) params: map[string]string{} path: '/test' base_path: '' } } struct_creation_time := time.since(start_time3) avg_struct_creation := f64(struct_creation_time.microseconds()) / f64(iterations) println(' 平均结构体创建: ${avg_struct_creation:.3f}μs') // 测试字符串操作 test_string := '/api/:version/users/:user_id/posts/:post_id' start_time4 := time.now() for _ in 0 .. iterations { _ := test_string.replace(':', 'X') } string_replace_time := time.since(start_time4) avg_string_replace := f64(string_replace_time.microseconds()) / f64(iterations) println(' 平均字符串替换: ${avg_string_replace:.3f}μs') start_time5 := time.now() for _ in 0 .. iterations { _ := test_string.split('/') } string_split_time := time.since(start_time5) avg_string_split := f64(string_split_time.microseconds()) / f64(iterations) println(' 平均字符串分割: ${avg_string_split:.3f}μs') } fn test_implementation_comparison() { println('\n📊 对比不同实现方式...') route_path := '/api/:version/users/:user_id/posts/:post_id' test_path := '/api/v1/users/123/posts/456' // 方式1: 当前实现 mut router1 := hono.ContextHybridRouter.new() handler1 := hono.ContextHandler{ path: route_path handler: fn (mut c hono.Context) http.Response { return c.text('test') } } router1.add_route('GET', handler1, '') start_time1 := time.now() for _ in 0 .. 1000 { router1.clear_cache() router1.clear_regex_cache() router1.match_route('GET', test_path) } current_impl_time := time.since(start_time1) avg_current := f64(current_impl_time.microseconds()) / 1000.0 println(' 当前实现平均: ${avg_current:.3f}μs') // 方式2: 预编译正则表达式 precompiled_regex := regex.regex_opt('^/api/(?P[^/]+)/users/(?P[^/]+)/posts/(?P[^/]+)$') or { println(' ❌ 预编译失败') return } start_time2 := time.now() for _ in 0 .. 1000 { if precompiled_regex.matches_string(test_path) { mut params := map[string]string{} params['version'] = precompiled_regex.get_group_by_name(test_path, 'version') params['user_id'] = precompiled_regex.get_group_by_name(test_path, 'user_id') params['post_id'] = precompiled_regex.get_group_by_name(test_path, 'post_id') } } precompiled_time := time.since(start_time2) avg_precompiled := f64(precompiled_time.microseconds()) / 1000.0 println(' 预编译实现平均: ${avg_precompiled:.3f}μs') if avg_current > avg_precompiled { improvement_potential := avg_current / avg_precompiled println(' 🎯 优化潜力: ${improvement_potential:.2f}x') } }