C++容器工作效率-内存操作

在之前轨迹的中看到了一段代码:

TrajectoryAnalyzer()类中一个 构造函数,函数接收的是轨迹信息。在个构造函数中使用std::vector管理轨迹点,其实是逐个轨迹点push_back。

同时又看了一地段Eigen的代码,同样使用了std:vector,但是使用了自己内存分配器:

template>

class vector: protect _Vector_base

同样的vector使用默认的或者用户实现的分配器件在性能上有什么区别?vector的表现又是如何?

先看一段测试程序:

#include 
#include 
#include "time.hpp"

struct Point
{
        Point() = default;
        Point(double x_,double y_,double z_,double h_,double v_)
        {
                //std::cout<<"Create Point with params : "<
struct MyAllocator {
        using value_type = T;

        MyAllocator() noexcept {}

        template
        MyAllocator(const MyAllocator&) noexcept {}

        template
        void construct(T* p, Args&&... args)
        {
                //std::cout << "Constructing one at "<< p <(args)...);
        };

        T* allocate(std::size_t n) {
                std::cout<<"Try to allocate "< std::size_t(-1) / sizeof(T)) {
                        throw std::bad_alloc();
                }
                if (auto p = static_cast(std::malloc(n * sizeof(T)))) {
                        return p;
                }
                throw std::bad_alloc();
        }

        void deallocate(T* p, std::size_t) noexcept {
                std::cout<<"Release all the region"<>
using MyVector = std::vector;

int main() {

        MyVector myVector;
        myVector.reserve(1024);

        std::cout<<"Try to push 1024 elements "< v;
        v.reserve(1024);

        std::cout<

解释一下提交allocator是一个类,类的表达是有格式的。按照格式分别实现:

1,分配内存 - 使用operator new(只分配不构造)

2,销毁内存 - free(看来operator new就是malloc)

3,构造对象 - placement new (在一个地址上构造一个对象)

4,插入对象 - (1)当用户使用自己的分配器,并且有construct函数时候,不论push_back或emplace_back一律调用construct在容器中构造对象。

                    -  (2)当使用默认的分配器时候,push_back和emplace_back的表现不一致,push_back耗时明显大于emplace_back。

5,时间函数 - 前后对比,判断耗时。

下面把测试结果分别显示一下:

测试环境:jetson orin ubuntu 20.04

1,默认的分配方式push_back插入数据和用户自定义的allocator插入数据比较:

Try to allocate 40960 bytes
Try to push 1024 elements
2023-09-15 16:05:39.879776909
2023-09-15 16:05:39.879906062
1
2
3
4
5
2023-09-15 16:05:39.879963790
2023-09-15 16:05:39.880002639

12953 ns
38849 ns

用户分配器使用placement new在已分配好的内存上构造13微秒

使用默认的分配器耗时明显比多。

2,默认的分配方式emplace_back插入数据和用户自定义的allocator插入数据比较:

2023-09-15 16:46:17.482801219
2023-09-15 16:46:17.482927142
1
2
3
4
5
2023-09-15 16:46:17.482970918
2023-09-15 16:46:17.483009799


125923 ns
38881  ns

使用emplace_back速度优于用户实现的插入操作。

总结:

1,我们看到代码中针对vector先使用reserve操作,预分配了一块内存,因此在插入过程中没有动态的更具内存大小实时调整,vector的调整是有拷贝的,把旧的数据内容拷贝到新的内存空间中。因此,vector预留内存的做法耗时较小,可以和没有reserve的vector比较一下:reserve预先分配内存方式下耗时小。

2,如果真有效率考量的话,还是建议使用emplace_back的操作,原理就是placement_new操作。在一块已知的内存上构造一个元素。

3,再次体验了一下C++中内存操作,作为语言C++考虑确实比较全面:

        (1),只分配不构造

        (2),分配和构造

        (3),在一块空闲内存上分配对象

     这也是new的三种不同用法。

谢谢

你可能感兴趣的:(c++,开发语言)