C++ 像C+一样大量使用共享ptr造成的性能损失+;正在收集垃圾?

C++ 像C+一样大量使用共享ptr造成的性能损失+;正在收集垃圾?,c++,performance,shared-ptr,C++,Performance,Shared Ptr,我想知道引用计数的shared_ptrs的性能问题,因此我编写了一个哑巴程序,它以一种非常低效的方式计算pow(2,n),使用数百万的内存分配和释放,以测试shared_ptrs,同时不让编译器优化一切,即使完全优化 用, g++ t.cpp -std=c++11 -ot -DV_ -pedantic -Ofast -s -fwhole-program 其中-DV_uu表示使用std::vector作为容器 作为 valgrind ./t 10000 这意味着要计算pow(21000)告诉我

我想知道引用计数的
shared_ptr
s的性能问题,因此我编写了一个哑巴程序,它以一种非常低效的方式计算
pow(2,n)
,使用数百万的内存分配和释放,以测试
shared_ptr
s,同时不让编译器优化一切,即使完全优化

用,

g++ t.cpp -std=c++11 -ot -DV_ -pedantic -Ofast -s -fwhole-program
其中-DV_uu表示使用
std::vector
作为容器

作为

valgrind ./t 10000
这意味着要计算
pow(21000)
告诉我

total heap usage: 45,174,051 allocs, 45,174,051 frees, 783,160,061 bytes allocated

输出

real    0m1.698s
user    0m1.693s
sys     0m0.004s
考虑到堆分配完成的数量,这是惊人的快。该系统是一台配备i5cpu和Ubuntu Linux操作系统的笔记本电脑

我在这里使用的基本模式是定义容器类,将
shared_ptr
扩展到其原始类

#if defined(V_)
    #define C_ std::vector
#elif defined(L_)
    #define C_ std::list
#elif defined(D_)
    #define C_ std::deque
#else
    #error
#endif

template<typename T>
class Container : public std::shared_ptr<C_<T>>
{
public:
    Container():
        std::shared_ptr<C_<T>>(new C_<T>)
    {
    }
};

class String : public std::shared_ptr<std::string>
{
public:
    String():
        std::shared_ptr<std::string>(new std::string)
    {
    }
    String(const char* s):
        std::shared_ptr<std::string>(new std::string(s))
    {
    }
    const char* getCString()
    {
        return get()->c_str();
    }
};

请注意,共享_ptr并不打算从中继承,至少不是公共继承和多态行为。一种方式是缺乏虚拟函数和虚拟析构函数。我认为“垃圾收集”的想法从根本上是误导的。正如Eric Raymond所说,垃圾收集模拟无限内存。C++没有垃圾收集,而且不会产生垃圾;相反,它产生了所有权和责任。共享指针的用途是表示共享所有权。使用共享指针,当你需要共享所有权时,“java或C++都能提供比C++更好的效率”——你问的是关于共享指针的基本问题,告诉我们C++比那些语言同时生产力低?“KerrekSB,你是说Raymond Chen不?”(我起初以为这篇文章是埃里克·利珀特写的,后来我的大脑表现出了未定义的行为。)
#if defined(V_)
    #define C_ std::vector
#elif defined(L_)
    #define C_ std::list
#elif defined(D_)
    #define C_ std::deque
#else
    #error
#endif

template<typename T>
class Container : public std::shared_ptr<C_<T>>
{
public:
    Container():
        std::shared_ptr<C_<T>>(new C_<T>)
    {
    }
};

class String : public std::shared_ptr<std::string>
{
public:
    String():
        std::shared_ptr<std::string>(new std::string)
    {
    }
    String(const char* s):
        std::shared_ptr<std::string>(new std::string(s))
    {
    }
    const char* getCString()
    {
        return get()->c_str();
    }
};
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <memory>

#if defined(V_)
    #define C_ std::vector
#elif defined(L_)
    #define C_ std::list
#elif defined(D_)
    #define C_ std::deque
#else
    #error
#endif

void check(bool isOkay)
{
    if (!isOkay)
    {
        std::exit(EXIT_FAILURE);
    }
}

template<typename T>
class Container : public std::shared_ptr<C_<T>>
{
public:
    Container():
        std::shared_ptr<C_<T>>(new C_<T>)
    {
    }
};

class String : public std::shared_ptr<std::string>
{
public:
    String():
        std::shared_ptr<std::string>(new std::string)
    {
    }
    String(const char* s):
        std::shared_ptr<std::string>(new std::string(s))
    {
    }
    const char* getCString() const
    {
        return get()->c_str();
    }
};

class SlowInteger : public Container<int>
{
public:
    SlowInteger()
    {
    }
    SlowInteger(int n)
    {
        check(0 <= n && n < 20);
        if (n < 10)
        {
            get()->push_back(n);
        }
        else
        {
            get()->push_back(n - 10);
            get()->push_back(1);
        }
    }
    int toInt() const
    {
        if (get()->size() == 1)
        {
            return get()->front();
        }
        else
        {
            return get()->front() + 10 * get()->back();
        }
    }
};

class VerySlowInteger : public Container<SlowInteger>
{
public:
    VerySlowInteger(String stringNumber)
    {
        for (auto it = stringNumber->rbegin(); it != stringNumber->rend(); ++it)
        {
            get()->push_back(SlowInteger(*it - '0'));
        }
    }
    void x2()
    {
        int m = 0;
        for (auto it = get()->begin(); it != get()->end(); ++it)
        {
            int n = it->toInt() * 2;
            if (n < 10)
            {
                *it = SlowInteger(m + n);
                m = 0;
            }
            else
            {
                *it = SlowInteger(n - 10 + m);
                m = 1;
            }
        }
        if (m == 1)
        {
            get()->push_back(SlowInteger(1));
        }
    }
    void x2n(int n)
    {
        check(n > 0);
        for (int i = 0; i < n; ++i)
        {
            x2();
        }
    }
    String toString()
    {
        String s;
        for (auto it = get()->rbegin(); it != get()->rend(); ++it)
        {
            s->push_back(it->toInt() + '0');
        }
        return s;
    }
};

int main(int argc, char **argv)
{
    check(argc == 2);
    int n = std::atoi(argv[1]);
    check(n > 0);
    VerySlowInteger nSlow("1");
    nSlow.x2n(n);
    String s = nSlow.toString();
    std::cout << s.getCString() << std::endl;
    return EXIT_SUCCESS;
}