From cd2cad350aa8ba51bec9a2e5720c2eb7c31749f0 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 15:10:30 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Cache=20RegExp=20in=20parsi?= =?UTF-8?q?ng=20adapters=20to=20improve=20performance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract inline RegExp instantiations from hot-path parsing loops and methods in NexusPHP adapters into lazily evaluated top-level final variables. This prevents repeated compilation during isolate execution and large list iterations. Co-authored-by: JustLookAtNow <12379683+JustLookAtNow@users.noreply.github.com> --- lib/services/api/nexusphp_adapter.dart | 35 ++++++++++++---------- lib/services/api/nexusphp_web_adapter.dart | 16 ++++++---- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/lib/services/api/nexusphp_adapter.dart b/lib/services/api/nexusphp_adapter.dart index 2924535..2dc819f 100644 --- a/lib/services/api/nexusphp_adapter.dart +++ b/lib/services/api/nexusphp_adapter.dart @@ -9,6 +9,11 @@ import 'package:pt_mate/services/site_config_service.dart'; import '../../utils/format.dart'; import 'nexusphp_helper.dart'; +// ⚡ Bolt: Cache RegExp to avoid recompiling it in list parsing loops, +// minimizing object allocations and improving performance when iterating +// over search categories. +final RegExp _whitespaceRegExp = RegExp(r'[\s\u200B-\u200D\uFEFF]'); + /// NexusPHP 站点适配器 /// 实现 NexusPHP (1.9+) 站点的 API 调用 class NexusPHPAdapter with NexusPHPHelper implements SiteAdapter { @@ -39,7 +44,9 @@ class NexusPHPAdapter with NexusPHPHelper implements SiteAdapter { await _loadTagMapping(); swDiscount.stop(); if (kDebugMode) { - _logger.d('NexusPHPAdapter.init: 加载优惠映射耗时=${swDiscount.elapsedMilliseconds}ms'); + _logger.d( + 'NexusPHPAdapter.init: 加载优惠映射耗时=${swDiscount.elapsedMilliseconds}ms', + ); } _dio = Dio( @@ -75,7 +82,9 @@ class NexusPHPAdapter with NexusPHPHelper implements SiteAdapter { ); swInterceptors.stop(); if (kDebugMode) { - _logger.d('NexusPHPAdapter.init: 配置Dio与拦截器耗时=${swInterceptors.elapsedMilliseconds}ms'); + _logger.d( + 'NexusPHPAdapter.init: 配置Dio与拦截器耗时=${swInterceptors.elapsedMilliseconds}ms', + ); } swTotal.stop(); if (kDebugMode) { @@ -91,9 +100,7 @@ class NexusPHPAdapter with NexusPHPHelper implements SiteAdapter { SiteType.nexusphp, ); if (template?.discountMapping != null) { - _discountMapping = Map.from( - template!.discountMapping, - ); + _discountMapping = Map.from(template!.discountMapping); } final specialMapping = await SiteConfigService.getDiscountMapping( _siteConfig.baseUrl, @@ -283,8 +290,6 @@ class NexusPHPAdapter with NexusPHPHelper implements SiteAdapter { } } - - final name = item['name'] as String; final smallDescr = item['small_descr'] as String? ?? ''; @@ -311,8 +316,6 @@ class NexusPHPAdapter with NexusPHPHelper implements SiteAdapter { } } - - return TorrentItem( id: (item['id'] as int).toString(), name: name, @@ -369,7 +372,11 @@ class NexusPHPAdapter with NexusPHPHelper implements SiteAdapter { } @override - Future fetchComments(String id, {int pageNumber = 1, int pageSize = 20}) async { + Future fetchComments( + String id, { + int pageNumber = 1, + int pageSize = 20, + }) async { try { final response = await _dio.get( '/api/v1/comments', @@ -506,9 +513,7 @@ class NexusPHPAdapter with NexusPHPHelper implements SiteAdapter { Future> getSearchCategories() async { // 通过baseUrl匹配预设配置 final defaultCategories = - await SiteConfigService.getDefaultSearchCategories( - _siteConfig.baseUrl, - ); + await SiteConfigService.getDefaultSearchCategories(_siteConfig.baseUrl); // 如果获取到默认分类配置,则直接返回 if (defaultCategories.isNotEmpty) { @@ -536,13 +541,13 @@ class NexusPHPAdapter with NexusPHPHelper implements SiteAdapter { for (final section in sectionsData) { final sectionName = section['name'] as String; final sectionDisplayName = (section['display_name'] as String) - .replaceAll(RegExp(r'[\s\u200B-\u200D\uFEFF]'), ''); + .replaceAll(_whitespaceRegExp, ''); final categoriesData = section['categories'] as List; for (final category in categoriesData) { final categoryId = category['id']; final categoryName = (category['name'] as String).replaceAll( - RegExp(r'[\s\u200B-\u200D\uFEFF]'), + _whitespaceRegExp, '', ); categories.add( diff --git a/lib/services/api/nexusphp_web_adapter.dart b/lib/services/api/nexusphp_web_adapter.dart index de866d1..cc02b38 100644 --- a/lib/services/api/nexusphp_web_adapter.dart +++ b/lib/services/api/nexusphp_web_adapter.dart @@ -88,6 +88,15 @@ Future _parseSearchResponseInIsolate( ); } +// ⚡ Bolt: Cache RegExp objects used in background isolates as top-level final +// variables. Caching these objects outside of the static class methods prevents +// recompilation on hot paths (e.g., list rendering and HTML parsing). +final RegExp _sizeRegExp = RegExp(r'([\d.]+)\s*(\w+)'); +final RegExp _htmlUrlRegExp = RegExp( + r'(src|href)="((?!https?://|//|data:|javascript:|#)[^"]+)"', + caseSensitive: false, +); + /// NexusPHP Web站点适配器 /// 用于处理基于Web接口的NexusPHP站点 class NexusPHPWebAdapter extends SiteAdapter @@ -1147,7 +1156,7 @@ class NexusPHPWebAdapter extends SiteAdapter // 解析文件大小为字节数 int sizeInBytes = 0; if (sizeText.isNotEmpty) { - final sizeMatch = RegExp(r'([\d.]+)\s*(\w+)').firstMatch(sizeText); + final sizeMatch = _sizeRegExp.firstMatch(sizeText); if (sizeMatch != null) { final sizeValue = double.tryParse(sizeMatch.group(1) ?? '0') ?? 0; final unit = sizeMatch.group(2)?.toUpperCase() ?? 'B'; @@ -1303,10 +1312,7 @@ class NexusPHPWebAdapter extends SiteAdapter } else { // HTML 模式:处理相对URL extractedContent = extractedContent.replaceAllMapped( - RegExp( - r'(src|href)="((?!https?://|//|data:|javascript:|#)[^"]+)"', - caseSensitive: false, - ), + _htmlUrlRegExp, (match) { final attr = match.group(1); final path = match.group(2)!;