WTSCollection vs STL容器 - 核心优势分析

为什么不直接用STL容器?

1. 🔧 自动内存管理 - 核心优势

STL容器的问题:
// ❌ 传统STL方式 - 容易内存泄漏
std::vector<TradeData*> trades;
trades.push_back(new TradeData("AAPL", 150.0, 1000));
trades.push_back(new TradeData("MSFT", 280.0, 2000));

// 程序员必须记住手动清理,容易忘记
for(auto* trade : trades) {
    delete trade;  // 忘记这行 = 内存泄漏
}

// ❌ 使用shared_ptr - 与现有系统不兼容
std::vector<std::shared_ptr<TradeData>> trades;
// 问题:TradeData已经继承WTSObject,有自己的引用计数系统
// 现在有两套引用计数系统,容易混乱
WTSCollection的解决方案:
// ✅ WTSCollection - 自动管理
WTSArray* trades = WTSArray::create();
trades->append(new TradeData("AAPL", 150.0, 1000));  // 自动retain()
trades->append(new TradeData("MSFT", 280.0, 2000));  // 自动retain()

trades->release();  // 自动清理所有元素,调用每个元素的release()

2. 🎯 统一的对象生命周期管理

交易系统的特殊需求:
// 交易系统中,对象经常在多个地方被引用:
TradeData* trade = new TradeData("AAPL", 150.0, 1000);

// 同时被多个容器引用
orderBook->addTrade(trade);      // 订单簿需要这个交易
riskManager->checkTrade(trade);  // 风控模块需要检查
logger->logTrade(trade);         // 日志模块需要记录

// 问题:谁负责删除这个对象?
WTSCollection的解决方案:
// ✅ 引用计数自动管理生命周期
TradeData* trade = new TradeData("AAPL", 150.0, 1000);  // 引用计数=1

orderBook->addTrade(trade);      // 内部调用retain(),引用计数=2
riskManager->checkTrade(trade);  // 内部调用retain(),引用计数=3  
logger->logTrade(trade);         // 内部调用retain(),引用计数=4

// 当各模块不再需要时,自动调用release()
// 当引用计数降到0时,对象自动删除

3. ⚡ 性能优化 - 针对交易系统

标准容器的性能问题:
// shared_ptr的开销
std::vector<std::shared_ptr<TradeData>> trades;
// 还有额外的控制块开销
// 原子操作的开销

// 访问时的间接开销
auto trade = trades[0];  // 需要通过shared_ptr访问
double price = trade->getPrice();  // 额外的间接访问
WTSCollection的性能优势:
// 直接指针,更好的性能
WTSArray* trades = WTSArray::create();
TradeData* trade = trades->at<TradeData>(0);  // 直接指针访问
double price = trade->getPrice();  // 无额外间接开销

// 自定义哈希表优化
WTSHashMap<std::string>* marketData = WTSHashMap<std::string>::create();
// 使用wt_hashmap,可能针对交易数据的访问模式优化了:
// - 哈希算法
// - 内存分配策略  
// - 冲突解决方案

4. 🔒 线程安全的引用计数

STL容器的线程安全问题:
// ❌ 不是线程安全的
std::vector<TradeData*> trades;

// 线程1
trades.push_back(newTrade);  // 不安全

// 线程2  
TradeData* trade = trades[0];  // 可能崩溃
delete trade;  // 其他线程可能还在使用
WTSCollection的线程安全:
// ✅ 引用计数是线程安全的
WTSArray* trades = WTSArray::create();

// 线程1
TradeData* trade = trades->grab<TradeData>(0);  // 原子操作增加引用计数
// 使用trade...
trade->release();  // 原子操作减少引用计数

// 线程2
TradeData* sameTrade = trades->grab<TradeData>(0);  // 安全获取
// 使用sameTrade...
sameTrade->release();  // 安全释放

5. 🎨 API一致性 - 降低学习成本

STL容器API不一致:
std::vector<int> vec;
std::map<string, int> map;  
std::queue<int> queue;

vec.push_back(1);    // 不同的添加方法
map["key"] = 1;      // 不同的添加方法
queue.push(1);       // 不同的添加方法

vec.size();          // 一致
map.size();          // 一致  
queue.size();        // 一致

// 但是清理方式不同
vec.clear();         // 简单清理
map.clear();         // 简单清理
// queue没有clear()方法!
WTSCollection统一API:
// 统一的创建方式
WTSArray* array = WTSArray::create();
WTSMap<string>* map = WTSMap<string>::create();
WTSHashMap<string>* hashMap = WTSHashMap<string>::create();
WTSQueue* queue = WTSQueue::create();

// 统一的大小获取
array->size();
map->size();
hashMap->size();
queue->size();

// 统一的清理方式
array->release();    // 自动清理所有元素
map->release();      // 自动清理所有元素
hashMap->release();  // 自动清理所有元素
queue->release();    // 自动清理所有元素

6. 🏗️ 专门为交易系统设计

交易系统的特殊需求:
// 1. 大量小对象的频繁创建和销毁
// 2. 对象在多个模块间传递
// 3. 严格的内存管理要求
// 4. 高性能要求
// 5. 类型安全要求
WTSCollection的针对性设计:
// ✅ 专门优化
class WTSArray : public WTSObject  // 容器本身也是WTSObject
{
    std::atomic<bool> _holding;    // 线程同步优化
    
    // 针对交易数据优化的方法
    void sort(SortFunc func);      // 内置排序,常用于价格排序
    uint32_t idxOf(WTSObject* obj); // 快速查找索引
    
    // 两种访问模式
    WTSObject* at(uint32_t idx);    // 不增加引用,适合临时访问
    WTSObject* grab(uint32_t idx);  // 增加引用,适合长期持有
};

实际应用场景对比

场景1:实时行情处理

// ❌ STL方式 - 复杂且容易出错
std::unordered_map<std::string, std::shared_ptr<TickData>> marketData;
std::vector<std::shared_ptr<TickData>> tickHistory;

void onTick(const std::string& symbol, double price, int volume) {
    auto tick = std::make_shared<TickData>(symbol, price, volume);
    marketData[symbol] = tick;        // 引用计数+1
    tickHistory.push_back(tick);      // 引用计数+1
    
    // 需要手动管理历史数据大小
    if(tickHistory.size() > 10000) {
        tickHistory.erase(tickHistory.begin());  // 复杂的清理逻辑
    }
}

// ✅ WTSCollection方式 - 简洁且安全
WTSHashMap<std::string>* marketData = WTSHashMap<std::string>::create();
WTSArray* tickHistory = WTSArray::create();

void onTick(const std::string& symbol, double price, int volume) {
    TickData* tick = new TickData(symbol, price, volume);
    marketData->add(symbol, tick);    // 自动管理引用计数
    tickHistory->append(tick);        // 自动管理引用计数
    
    // 简单的大小管理
    if(tickHistory->size() > 10000) {
        tickHistory->clear();         // 自动清理所有元素
    }
}

场景2:订单管理

// ❌ STL方式 - 内存管理复杂
class OrderManager {
    std::map<std::string, Order*> activeOrders;
    std::queue<Order*> pendingOrders;
    
public:
    ~OrderManager() {
        // 必须手动清理所有容器
        for(auto& pair : activeOrders) {
            delete pair.second;
        }
        while(!pendingOrders.empty()) {
            delete pendingOrders.front();
            pendingOrders.pop();
        }
    }
};

// ✅ WTSCollection方式 - 自动管理
class OrderManager {
    WTSMap<std::string>* activeOrders;
    WTSQueue* pendingOrders;
    
public:
    OrderManager() {
        activeOrders = WTSMap<std::string>::create();
        pendingOrders = WTSQueue::create();
    }
    
    ~OrderManager() {
        activeOrders->release();   // 自动清理所有订单
        pendingOrders->release();  // 自动清理所有订单
    }
};

总结

WTSCollection不是为了重新发明轮子,而是为了解决交易系统中的特定问题:

  1. 自动内存管理 - 避免内存泄漏,减少程序员负担
  2. 统一对象生命周期 - 适配现有的WTSObject引用计数系统
  3. 性能优化 - 针对交易系统的访问模式优化
  4. 线程安全 - 引用计数的原子操作
  5. API一致性 - 降低学习和使用成本
  6. 类型安全 - 统一的WTSObject基类系统

这些优势在高频交易、实时风控、大量数据处理等场景下尤为重要,能显著提高代码质量和系统稳定性。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐