You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过C语言优化Python核心类的技术咨询

优化特征存储核心类的思路与实践

嘿,看起来你要优化的是一个用来存储特征字典的底层核心类——每个特征对应一个已排序的列表,还得支持任意数据类型,这种场景在特征工程、推荐系统里可太常见了。结合你的需求,我整理了几个关键优化方向和可落地的方案:

1. 明确排序规则与类型约束,避免隐性问题

当前的实现里,排序后的列表如果遇到不同类型的元素,很容易出现排序报错(比如数字和字符串混排),而且没有明确的校验逻辑。我们可以给每个特征绑定排序键函数和类型校验器,确保每个特征的元素类型一致,排序逻辑透明:

from typing import Any, Callable, Dict, List, Tuple
import bisect

class OptimizedFeatureStore:
    def __init__(self):
        # 存储结构:{特征名: (有序列表, 排序键函数, 类型校验函数)}
        self._data: Dict[str, Tuple[List[Any], Callable[[Any], Any], Callable[[Any], bool]]] = {}

    def register_feature(self, feature_name: str, initial_data: List[Any], sort_key: Callable[[Any], Any], type_check: Callable[[Any], bool]):
        """注册新特征,初始化时校验类型并排序"""
        if not all(type_check(item) for item in initial_data):
            raise TypeError(f"特征 {feature_name} 的所有元素必须通过类型校验")
        # 提前排序后存入
        sorted_data = sorted(initial_data, key=sort_key)
        self._data[feature_name] = (sorted_data, sort_key, type_check)

2. 优化插入与查询效率,避免全量排序

原来如果要往列表里加新元素,直接append再排序的时间复杂度是O(n log n),数据量大的时候效率很低。我们可以用二分查找找到插入位置,用bisect.insort保持列表有序(时间复杂度O(n),但比全量排序好很多);查询时也可以用二分快速定位目标元素:

def insert_item(self, feature_name: str, item: Any):
    """向指定特征插入元素,自动保持有序"""
    if feature_name not in self._data:
        raise KeyError(f"未找到特征 {feature_name}")
    data_list, sort_key, type_check = self._data[feature_name]
    if not type_check(item):
        raise TypeError(f"元素 {item} 不符合特征 {feature_name} 的类型要求")
    # 用bisect找到插入位置,维持有序
    bisect.insort(data_list, item, key=sort_key)

def query_items_by_key(self, feature_name: str, target_key) -> List[Any]:
    """根据排序键快速查询匹配的元素"""
    if feature_name not in self._data:
        return []
    data_list, sort_key, _ = self._data[feature_name]
    # 构造虚拟元素用于二分查找边界
    # 这里假设你的元素是(键, 值)结构,可根据实际格式调整
    dummy_item = (target_key, None)
    left_idx = bisect.bisect_left(data_list, dummy_item, key=lambda x: sort_key(x))
    right_idx = bisect.bisect_right(data_list, dummy_item, key=lambda x: sort_key(x))
    return data_list[left_idx:right_idx]

3. 增强类型安全与可读性,用泛型约束特征类型

如果希望每个特征的类型更明确,可以用Python的泛型(Generic)来实现类型约束,让代码可读性更强,也能提前发现类型错误:

from typing import Generic, TypeVar

T = TypeVar('T')

class TypedFeatureList(Generic[T]):
    """单个特征的类型化有序列表"""
    def __init__(self, sort_key: Callable[[T], Any], type_check: Callable[[T], bool]):
        self._data: List[T] = []
        self._sort_key = sort_key
        self._type_check = type_check

    def add_items(self, items: List[T]):
        if not all(self._type_check(item) for item in items):
            raise TypeError("元素不符合特征类型要求")
        self._data.extend(items)
        self._data.sort(key=self._sort_key)

    def insert_item(self, item: T):
        if not self._type_check(item):
            raise TypeError("元素不符合特征类型要求")
        bisect.insort(self._data, item, key=self._sort_key)

# 顶层特征存储类
class FeatureStore:
    def __init__(self):
        self._features: Dict[str, TypedFeatureList[Any]] = {}

    def register_typed_feature(self, feature_name: str, sort_key: Callable[[Any], Any], type_check: Callable[[Any], bool]):
        self._features[feature_name] = TypedFeatureList(sort_key, type_check)

4. 序列化与持久化优化

如果这个类需要频繁存盘或网络传输,可以用高效的序列化方案,比如pickle的高版本协议,或者msgpack:

import pickle

def save(self, filepath: str):
    """将存储数据序列化到文件"""
    with open(filepath, 'wb') as f:
        # 使用最高版本的pickle协议,提升序列化效率
        pickle.dump(self._data, f, protocol=pickle.HIGHEST_PROTOCOL)

@classmethod
def load(cls, filepath: str) -> 'OptimizedFeatureStore':
    """从文件加载序列化数据"""
    store = cls()
    with open(filepath, 'rb') as f:
        store._data = pickle.load(f)
    return store

5. 性能监控与调优

可以加入简单的性能统计,方便后续优化瓶颈:

import time

class OptimizedFeatureStore:
    def __init__(self):
        self._data = {}
        self._metrics = {
            'insert_count': 0,
            'query_count': 0,
            'total_insert_time': 0.0,
            'total_query_time': 0.0
        }

    def insert_item(self, feature_name: str, item: Any):
        start = time.time()
        # 原有插入逻辑...
        self._metrics['insert_count'] += 1
        self._metrics['total_insert_time'] += time.time() - start

    def query_items_by_key(self, feature_name: str, target_key) -> List[Any]:
        start = time.time()
        # 原有查询逻辑...
        result = data_list[left_idx:right_idx]
        self._metrics['query_count'] += 1
        self._metrics['total_query_time'] += time.time() - start
        return result

    def get_performance_metrics(self):
        """获取性能统计指标"""
        avg_insert_time = self._metrics['total_insert_time'] / max(self._metrics['insert_count'], 1)
        avg_query_time = self._metrics['total_query_time'] / max(self._metrics['query_count'], 1)
        return {
            **self._metrics,
            'avg_insert_time': round(avg_insert_time * 1000, 3),  # 转毫秒
            'avg_query_time': round(avg_query_time * 1000, 3)
        }

如果数据量特别大,还可以考虑引入第三方库sortedcontainers里的SortedList,它的插入和查询都是O(log n)时间复杂度,性能会更优。

内容的提问来源于stack exchange,提问作者Lzkatz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 10:01:16