Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Казалось бы достаточно было бы сделать STL'ный buffer.reserve. Но при каждом увеличении массива происходит создание НОВОГО нативного массива, а потом ещё и создание поштучно конструктором копии/переноса в нем всех уже существующих элементов. То есть — если мы не хотим добавлять конструктор переноса в класс наших объектов — то работать будет очень медленно.
template <typename T, unsigned int chunk_size = 100>
class PoolDeque
{
public:
PoolDeque(){}
inline T* get(){
if(free_ptrs.empty()){
makeMore();
}
T* obj = free_ptrs.back();
free_ptrs.pop_back();
return obj;
}
inline void free(T* obj){
free_ptrs.push_back(obj);
}
void clearPool(){
buffers.clear();
free_ptrs.clear();
}
private:
std::deque<T> buffers;
std::vector<T*> free_ptrs;
void makeMore(){
buffers.resize(buffers.size() + chunk_size);
for (int i = 0; i < chunk_size; ++i) {
buffers.emplace_back();
free_ptrs.emplace_back(&buffers.back());
}
}
};
void makeMore(){
int init_size = buffers.size();
int target_size = buffers.size() + chunk_size;
buffers.resize(target_size);
for (int i = init_size; i < target_size; ++i) {
//buffers.emplace_back();
free_ptrs.emplace_back(&buffers[i]);
}
}
PoolFactory: 0.026922s wall, 0.015600s user + 0.000000s system = 0.015600s CPU (57.9%)
PoolFactory: 0.026090s wall, 0.015600s user + 0.015600s system = 0.031200s CPU (119.6%)
PoolFactory: 0.026244s wall, 0.015600s user + 0.015600s system = 0.031200s CPU (118.9%)
PoolFactory: 0.026641s wall, 0.015600s user + 0.015600s system = 0.031200s CPU (117.1%)
PoolFactory: 0.027969s wall, 0.031200s user + 0.000000s system = 0.031200s CPU (111.6%)
PoolFactory: 0.027408s wall, 0.000000s user + 0.031200s system = 0.031200s CPU (113.8%)
std::vector: 0.018685s wall, 0.015600s user + 0.000000s system = 0.015600s CPU (83.5%)
std::vector: 0.019019s wall, 0.015600s user + 0.015600s system = 0.031200s CPU (164.0%)
std::vector: 0.019300s wall, 0.000000s user + 0.015600s system = 0.015600s CPU (80.8%)
std::vector: 0.018718s wall, 0.000000s user + 0.015600s system = 0.015600s CPU (83.3%)
std::vector: 0.018500s wall, 0.015600s user + 0.015600s system = 0.031200s CPU (168.7%)
std::vector: 0.020583s wall, 0.015600s user + 0.000000s system = 0.015600s CPU (75.8%)
#include <boost/timer/timer.hpp>
...
int main(int argc, char *argv[])
{
{
std::vector< BaseClass > ar;
ar.reserve(total);
boost::timer::auto_cpu_timer timer1;
for (int var = 0; var < total; ++var) {
ar.emplace_back(var);
}
timer1.stop();
std::cout <<"std::vector : ";
timer1.report();
}
{
std::vector< BaseClass* > ptr_ar;
PoolFactory<BaseClass> bPool;
ptr_ar.reserve(total);
boost::timer::auto_cpu_timer timer3;
for (int var = 0; var < total; ++var) {
ptr_ar.push_back(bPool.get(var));
}
timer3.stop();
std::cout <<"PoolFactory : ";
timer3.report();
}
}
PoolFactory: 0.027588s wall, 0.015600s user + 0.000000s system = 0.015600s CPU (56.5%)
PoolFactory 2: 0.011758s wall, 0.015600s user + 0.000000s system = 0.015600s CPU (132.7%)
…
std::vector: 0.018754s wall, 0.015600s user + 0.000000s system = 0.015600s CPU (83.2%)
std::vector 2: 0.010039s wall, 0.015600s user + 0.000000s system = 0.015600s CPU (155.4%)
…
std::vector< BaseClass > ar;
{
ar.reserve(total);
/// .... std::vector
ar.clear();
}
{
ar.reserve(total);
/// .... std::vector 2
ar.clear();
}
PoolFactory<BaseClass> bPool;
{
std::vector< BaseClass* > ptr_ar;
ptr_ar.reserve(total);
/// PoolFactory
bPool.freeAll();
}
{
std::vector< BaseClass* > ptr_ar;
ptr_ar.reserve(total);
/// PoolFactory 2
bPool.freeAll();
}
PoolFactory<BaseClass> bPool;
{
std::vector< BaseClass* > ptr_ar;
ptr_ar.reserve(total);
/// PoolFactory
bPool.freeAll();
}
{
std::vector< BaseClass* > ptr_ar;
ptr_ar.reserve(total);
/// PoolFactory 2
bPool.freeAll();
}
PoolFactory<BaseClass> bPool;
std::vector< BaseClass* > ptr_ar;
{
ptr_ar.reserve(total);
/// PoolFactory
bPool.freeAll();
}
{
ptr_ar.reserve(total);
/// PoolFactory 2
bPool.freeAll();
}
#include <boost/pool/singleton_pool.hpp>
class Data {
public:
void* operator new(size_t x);
void operator delete(void* ptr);
private:
int data[10];
};
class DataTag;
typedef boost::singleton_pool<DataTag, sizeof(Data)> DataPool;
void* Data::operator new(size_t x) {
return DataPool::malloc();
}
void Data::operator delete(void* ptr) {
DataPool::free(ptr);
}
int main() {
Data* data = new Data;
delete data;
}
sudo apt-get install libboost-system-dev
Объектный пул и быстрое создание объектов в куче