【性能】单例模式与指针直接使用方式对比

在写代码时,往往为了使用方便,将一些接口类设计为单例模式。

如果能够理清类之间的创建关系,最好将对象的指针传入要使用的对象中。

以下为同一台机器上进行的多次性能测试,性能差别还是比较明显的。

#include <stdlib.h>
#include <stdio.h>

class A
{
public:
    A() = default;
    ~A() = default;

    static A& get_instance()
    {
        static A my_intance;
        return my_intance;
    };

    void func()
    {
        printf("print func\n");
    }
};

int main()
{
    // A a;
    int count = 1000000000;
    while (count-- > 0)
    {
        A::get_instance().func();
        // a.func();
    }
    
    return 0;
}

测试结果:

单例模式测试结果

real    0m16.725s
user    0m16.540s
sys     0m0.180s

real    0m16.737s
user    0m16.561s
sys     0m0.170s

real    0m16.849s
user    0m16.684s
sys     0m0.160s

real    0m16.850s
user    0m16.686s
sys     0m0.160s

real    0m16.832s
user    0m16.667s
sys     0m0.160s

通过指针传递引用方式测试结果

real    0m15.821s
user    0m15.608s
sys     0m0.210s

real    0m15.932s
user    0m15.806s
sys     0m0.120s

real    0m16.218s
user    0m16.043s
sys     0m0.170s

real    0m16.061s
user    0m15.877s
sys     0m0.180s

real    0m16.008s
user    0m15.833s
sys     0m0.170s

10亿次输出单条log,性能差距将近10%

=======================

将上述创建A对象的方式用shared_ptr的方式,这效率能与原始指针的方式差距更大,约20%
测试程序:
 

#include <stdlib.h>
#include <stdio.h>
#include <memory>

class A
{
public:
    A() = default;
    ~A() = default;

    static A& get_instance()
    {
        static A my_intance;
        return my_intance;
    };

    void func()
    {
        printf("print func\n");
    }
};

int main()
{
    auto p = std::make_shared<A>();
    int count = 1000000000;
    while (count-- > 0)
    {
        // A::get_instance().func();
        // a.func();
        p->func();
    }
    
    return 0;
}

测试结果: 

real    0m20.193s
user    0m19.970s
sys     0m0.220s

real    0m19.380s
user    0m19.207s
sys     0m0.160s

real    0m19.389s
user    0m19.215s
sys     0m0.170s

如果存在shared_ptr赋值给weak_ptr,在weak_ptr使用时,追加 expired判断 和 转换为shared_ptr,效率就低的更可怕。

部分程序(类A没有变动):
 


int main()
{
    auto p = std::make_shared<A>();
    std::weak_ptr<A> w_p = p;
    int count = 1000000000;
    while (count-- > 0)
    {
        // A::get_instance().func();
        // a.func();
        if(!w_p.expired())
        {
            std::shared_ptr<A> sp = w_p.lock();
            sp->func();
        }
        
    }
    
    return 0;
}

测试结果:

real    1m2.789s
user    1m2.611s
sys     0m0.170s

real    1m2.371s
user    1m2.043s
sys     0m0.320s

real    1m3.127s
user    1m2.939s
sys     0m0.181s

另外补充:
unique_ptr的性能 比 直接使用对象 下降约50%
 

real    0m29.101s
user    0m28.915s
sys     0m0.180s

========================

real    0m16.162s
user    0m16.036s
sys     0m0.120s

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值