5

我为 MyOrder 类编写了自定义运算符 new 和 operator delete。我正在使用 boost::singleton 池分配内存。这是测试性能的程序,

#include <boost/pool/singleton_pool.hpp>
#include <boost/progress.hpp>
#include <iostream>
#include <new>
#include <vector>


class MyOrder{
    std::vector<int> v1_;
    std::vector<double> v2_;

    std::string s1_;
    std::string s2_;

public:
    MyOrder(std::string s1, std::string s2): s1_(s1), s2_(s2) {}

    ~MyOrder(){}

    static void * operator new(size_t size); 
    static void operator delete(void * rawMemory) throw();
};

struct MyOrderTag{};
typedef boost::singleton_pool<MyOrderTag, sizeof(MyOrder)> MyOrderPool; 

void* MyOrder:: operator new(size_t size)
{
    if (size != sizeof(MyOrder)) 
        return ::operator new(size);

    while(true){
        void * ptr = MyOrderPool::malloc();
        if (ptr != NULL) return ptr;

        std::new_handler globalNewHandler = std::set_new_handler(0);
        std::set_new_handler(globalNewHandler);

        if(globalNewHandler)  globalNewHandler();
        else throw std::bad_alloc();

    }
}

void MyOrder::operator delete(void * rawMemory) throw()
{
    if(rawMemory == 0) return; 
    MyOrderPool::free(rawMemory);
}

int main()
{
    MyOrder* mo = NULL; 
    std::vector<MyOrder*> v;
    v.reserve(100000);

    boost::progress_timer howlong;
    for(int i = 0; i< 100000; ++i)
    {
        mo = new MyOrder("Sanket", "Sharma");
        v.push_back(mo);
    }

    for (std::vector<MyOrder*>::const_iterator it = v.begin(); it != v.end(); ++it)
    {
        delete *it;
    }
    return 0;
}

我使用 -O2 标志编译了上述程序,并在我的 Macbook 上运行 2.26 GHz Intel Core 2 Duo,耗时 0.16 秒。然后我注释掉我声明和定义自定义运算符 new 和 operator delete 的行,使用 -O2 标志重新编译并在同一台机器上运行,耗时 0.13 秒。

使用 singleton_pool 为相同大小的对象分配和释放内存应该会加快速度。为什么让它变慢?还是创建池的开销抵消了在这个小程序中获得的性能优势?

更新:

我用一个 int 和一个 double 替换了两个 std::string 变量,这次在 3.0 GHZ AMD Phenom(tm) II X4 945 处理器上运行了两个程序,每个程序进行了 100000000 次(即之前的 1000 次)迭代。使用自定义内存分配的一项需要 3.2 秒,而使用默认内存分配的一项需要 8.26 秒。所以这次自定义内存分配获胜。

4

1 回答 1

5

我认为你的数字毫无意义。如果你只检查一次运行时,你发现0.13vs 0.16seconds than 那是完全没有意义的,并且由开销决定。

您必须运行要测试数千次的代码段,然后比较数据以排除开销。

不,实际上,0.03您的进程被关闭等很容易解释秒数差异。

于 2012-05-05T23:36:18.103 回答