因此,这个问题主要是由于类似以下的帖子引起的:
Why are new()/delete() slower than malloc()/free()?
在以下情况下考虑自己:
这个想法是要提出一个新的分配器类,它可以在两个方法malloc()
和std::allocator
之间“选择”。
假设如果您的类型不是 POD类型,您将使用namespace meta
{
template<bool, typename T>
struct Allocator_Impl;
template<typename T>
struct Allocator_Impl<true, T>
{
using type = Mallocator<T>;
};
template<typename T>
struct Allocator_Impl<false, T>
{
using type = std::allocator<T>;
};
template<typename T>
struct is_trivially_allocateable
{
using type = typename
std::conjunction<std::is_trivial<T>,
std::is_standard_layout<T>>::type;
constexpr static inline bool value = type::value;
};
}
template<typename T>
struct Allocator : public meta::Allocator_Impl<meta::is_trivially_allocateable<T>::value, T>
{};
,并使用这样的分配器,如下所述:https://en.cppreference.com/w/cpp/named_req/Allocator(Mallocator)< br />如果您的类型是是POD类型
现在,要选择分配器类,您将使用类似以下内容的内容:
vector
在此之后,要实施我们的“智能”?例如,我们可以简单地从旧的sna
类继承容器。假设这里的向量在另一个命名空间中,例如namespace sna
{
template<typename T> using allocTy = typename Allocator<T>::type;
template<typename T, class Alloc = allocTy<T>>
class vector : public std::vector<T, Alloc>
{
public:
typedef typename std::vector<T, Alloc>::size_type size_type;
typedef T value_type;
typedef Alloc allocator;
typedef std::vector<value_type, allocator> parent;
vector() : parent() {}
vector(const size_type n) :
parent(n)
... implement other constructors if needed ...
};
}
:
std::chrono::system_clock::time_point start, stop;
const size_t size = 100000000;
std::cout << "Allocating " << size << " doubles:" << std::endl;
start = std::chrono::high_resolution_clock::now();
std::vector<double> new_data(size);
stop = std::chrono::high_resolution_clock::now();
std::cout << "Duration with normal vector: ";
std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start).count() << " ns." << std::endl;
start = std::chrono::high_resolution_clock::now();
sna::vector<double> malloc_data(size);
stop = std::chrono::high_resolution_clock::now();
std::cout << "Duration with custom vector: ";
std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start).count() << " ns." << std::endl;
之后-为了确保-我也对分配时间进行了基准测试,并提出了:
分配1亿双:
法线向量的持续时间:281528400 ns。
带有自定义矢量的持续时间:1990600 ns。
对于基准测试,我使用了这段代码:
vector
对于此基准测试,我使用了-O2优化标志。
因此,对我来说,使用Mallocator
类的std::allocator
比使用std::vector
的{{1}}快一百倍,我认为这是相当可观的性能提升。
但除此之外:
这样的“把戏”是否被认为是不好的做法?或者,如果情况如上所述,您可以安全地使用这样的东西吗?是否会有另一个更好的解决方案,否则这将不值得付出努力,而我应该坚持使用{{1}}类型?