优化大字符串子串搜索效率:Python代码性能提升求助
优化Python子串搜索循环的高效方案
首先,咱们拆解下当前代码的性能瓶颈:每次循环里最多要做3次子串搜索(检查三种Symbolizer),再加上多次条件判断,这些操作在1000次循环里累加起来就拖慢了整体速度。下面给你几个针对性的提速方案,亲测能有效降低执行时间:
1. 减少不必要的子串搜索(最核心优化)
你会发现layer_geom是固定值(比如当前处理多边形图层时,它就是polygon),根本不需要另外两种Symbolizer的检查!只针对当前图层对应的Symbolizer做一次搜索就行,直接砍掉2/3的子串搜索操作。
同时,把排除的标题列表改成集合——集合的in操作是O(1),比元组的O(n)快得多,哪怕元素少,积少成多也有明显收益。
优化后的代码:
# 提前定义映射和排除集合,放在循环外部(只初始化一次) GEOM_TO_SYMBOLIZER = { 'polygon': 'PolygonSymbolizer', 'line': 'LineSymbolizer', 'point': 'PointSymbolizer' } EXCLUDED_TITLES = {'line', 'point', 'polygon', 'Polygon', 'Default Line', 'Default Point'} # 提前获取当前图层对应的目标Symbolizer,避免循环内重复查找 target_symbolizer = GEOM_TO_SYMBOLIZER[layer_geom] gs_styles = [] for style in all_available_gs_styles: title = style.sld_title if title is not None: title_str = str(title) if title_str not in EXCLUDED_TITLES: # 只做一次子串搜索,而非三次 if target_symbolizer in style.sld_body: gs_styles.append((style.name, title_str))
2. 用列表推导式替代显式循环+append
Python的列表推导式是底层优化过的,比手动写for循环加append要快不少,同时代码更简洁:
# 基于上面的提前定义,直接用列表推导式 gs_styles = [ (style.name, str(style.sld_title)) for style in all_available_gs_styles if (style.sld_title is not None and str(style.sld_title) not in EXCLUDED_TITLES and target_symbolizer in style.sld_body) ]
3. 预编译正则(复杂场景补充)
如果你的子串搜索需要更精准的匹配(比如Symbolizer必须是XML标签的一部分),可以预编译正则表达式替代in操作。不过对于简单的字面量匹配,in已经足够高效,这个方案适合有特殊匹配需求的场景:
import re # 预编译正则,转义特殊字符确保字面量匹配 target_pattern = re.compile(re.escape(target_symbolizer)) gs_styles = [ (style.name, str(style.sld_title)) for style in all_available_gs_styles if (style.sld_title is not None and str(style.sld_title) not in EXCLUDED_TITLES and target_pattern.search(style.sld_body) is not None) ]
额外小Tips
- 如果
style.sld_title本身就是字符串类型,可以去掉str()转换,减少不必要的类型操作; - 如果
all_available_gs_styles是数据库查询结果,可以考虑在数据库层面先过滤掉不符合条件的样式,减少内存中循环的数量。
按照方案1+方案2优化后,应该能把执行时间压到更理想的范围——毕竟砍掉了2/3的子串搜索操作,这是最直接的性能提升点。
内容的提问来源于stack exchange,提问作者user1919
相关产品推荐
相关产品推荐

