鲲鹏社区首页
中文
注册
开发者
我要评分
获取效率
正确性
完整性
易理解
在线提单
论坛求助

性能敏感流程中,避免临时对象申请

【说明】 在实际业务函数实现时,在主流程中定义仅用在部分场景下使用的临时变量,会增加函数运行时的固有开销;因此,需要尽可能避免仅在部分场景下使用的临时变量在主流程中定义。

【原理】 C++的对象实现机制上,class和struct类型的对象会存在相应的构造函数、析构函数等对象创建/销毁开销,如果构造函数、析构函数本身存在耗时操作,可能会带来性能损失。

【注意事项】 不涉及

【案例】

优化前
class ExceptionHandler {
public:
    ExceptionHandler()
    {
        of.open("sys_err.log");
    }
    ~ExceptionHandler()
    {
        of.close();
    }

    void Record(int32_t proc_type, int32_t errCause)
    {
        // 通过of向sys_err.log写入日志;
    }

private:
    std::ofstream of;
};

int32_t SomeProc(void *msg)
{
    ExceptionHandler exceptHandler();

    // main process
    int32_t result = SomeChildProc(...)
    if (result != OK) {
        exceptHandler.Record(PROC_TYPE_XXX, result);
    }
    return 0;
}

说明:上述函数SomeProc执行过程中,每次都会默认执行ExceptionHandler类的构造函数和析构函数,构造函数和析构函数中会存在文件操作等耗时处理,运行时开销增大。

优化后
class ExceptionHandler {
public:
    static ExceptionHandler &GetInstance()
    {
        static ExceptionHandler instance;
        return instance;
    }
    void Record(int32_t proc_type, int32_t errCause)
    {
        // 通过of向sys_err.log写入日志;
    }
private:
    ExceptionHandler()
    {
        of.open("sys_err.log");
    }
    ~ExceptionHandler()
    {
        of.close();
    }

private:
    std::ofstream of;
};
int32_t SomeProc(void *msg)
{
    // main process
    int32_t result = SomeChildProc(...)

    if (result != OK) {
        ExceptionHandler & expHandler = ExceptionHandler::GetInstance();
        expHandler.Record(PROC_TYPE_XXX, result);
    }
    return 0;
}

说明:修改后,ExceptionHandler作为单例模式,在SomeProc函数执行阶段,如果不发生SomeChildProc返回错误的情况,无异常处理影响。当然,此优化方法针对频繁输出日志的场景能够明显减少临时对象的创建与销毁,但是如果针对日志记录频度比较低,且时间上离散的场景,可能带来副作用,例如sys_err.log文件会持续保持打开状态,占用系统资源。