比较 C/C++ 中指针分配的性能

Comparing the Performance of Pointers' Allocation in C/C++

本文关键字:分配 性能 指针 C++ 比较      更新时间:2023-10-16

比较C/C 中指针分配/DE分配的最佳方法是什么?请将表演视为观点。

该代码包括以下动态分配类型的比较:

  • Malloc/Free
  • New/Delete
  • std::auto_ptr
  • std::shared_ptr
  • std::unique_ptr
  • std::allocator/deallocator

让我们从此代码段开始:

#include <stdlib.h> // I intended to use C for malloc. Though not cstdlib
#include <sys/time.h>
#include <iostream>
#include <memory>
#define Million 1000000
#define Alls 100 * Million
long calculate_time(struct timeval start, struct timeval end){
    long start_micro = (start.tv_sec * Million) + start.tv_usec;
    long end_micro = (end.tv_sec * Million) + end.tv_usec;
    long elapsed_time = end_micro - start_micro;
    std::cout << "Elapsed time: " << elapsed_time << " usec";
    std::cout << " (" << Alls / elapsed_time << " allocations/microseconds)" << std::endl;
}

/* 
* Version: C
* Allocation: Malloc
* Deallocation: Free
*/
void c_pointer (){

    int counter = 0;
    do{
        int *p = (int *) malloc (sizeof (int));
        *p =5;
        free(p);
        counter ++;
    } while (counter < Alls);
}

/* 
* Version: C++98
* Allocation: New
* Deallocation: Delete
*/
void cpp98_pointer (){
    int counter = 0;
    do{
        int *p = new int (5);
        delete p;
        counter ++;
    } while (counter < Alls);
}

/* 
* Version: C++98 till C++17
* Allocation: std::auto_ptr
* Deallocation: Automatically
*/
void cpp98_auto_ptr (){
    int counter = 0;
    do{
        std::auto_ptr<int> p(new int);
        *p = 5;
        counter ++;
    } while (counter < Alls);
}

/* 
* Version: C++11
* Allocation: std::shared_ptr
* Deallocation: Automatically
*/
void cpp11_shared_ptr (){
    int counter = 0;
    do{
        std::shared_ptr<int> p(new int);
        *p = 5;
        counter ++;
    } while (counter < Alls);
}

/* 
* Version: C++11
* Allocation: std::unique_ptr
* Deallocation: Automatically
*/
void cpp11_unique_ptr (){
    int counter = 0;
    do{
        std::unique_ptr<int> p(new int); 
        *p = 5;
        counter ++;
    } while (counter < Alls);
}

/* 
* Version: C++98
* Allocation: std::allocator
* Deallocation: Deallocate
*/
void cpp98_allocator (){
    int counter = 0;
    do{
        std::allocator<int> a;
        int* p = a.allocate(1);
        a.construct(p, 1);
        *p =5;
        a.deallocate(p, 1);
        counter ++;
    } while (counter < Alls);
}

int main (){
    for (int i= 0 ; i < 6; i++){
        struct timeval t1, t2;
        gettimeofday(&t1, NULL);
        switch(i){
            case 0:
                std::cout << "C - Malloc/Free:" << std::endl;
                c_pointer();
                break;
            case 1:
                std::cout << "C++98 - New/Delete:" << std::endl;
                cpp98_pointer();
                break;
            case 2:
                // From C++98 until C++17 (Removed in C++17)
                std::cout << "C++98 - auto_ptr:" << std::endl;
                cpp98_auto_ptr();
                break;
            case 3:
                // From C++11
                std::cout << "C++11 - shared_ptr:" << std::endl;
                cpp11_shared_ptr();
                break;
            case 4:
                // From C++11
                std::cout << "C++11 - unique_ptr:" << std::endl;
                cpp11_unique_ptr();
                break;
            default:
                // Deprecated in C++98
                std::cout << "C++98 - Default Allocator:" << std::endl;
                cpp98_allocator();
                break;
        }
        gettimeofday(&t2, NULL);
        calculate_time(t1, t2);
    }
    return 0;
}

在我自己的笔记本电脑上,结果如下:

C - Malloc/Free:
Elapsed time: 1519052 usec (65 allocations/microseconds)
C++98 - New/Delete:
Elapsed time: 1718064 usec (58 allocations/microseconds)
C++98 - auto_ptr:
Elapsed time: 2334505 usec (42 allocations/microseconds)
C++11 - shared_ptr:
Elapsed time: 10197285 usec (9 allocations/microseconds)
C++11 - unique_ptr:
Elapsed time: 11785931 usec (8 allocations/microseconds)
C++98 - Default Allocator:
Elapsed time: 3487610 usec (28 allocations/microseconds)

首先,当您使用零售优化打开时,您将获得截然不同的结果。(我的快速端口到Windows和您的代码中的一些修复程序,包括在COUT语句之后不进行计时测量):

C - Malloc/Free:
Elapsed time: 469 msec     (21321 allocations/second)
C++98 - New/Delete:
Elapsed time: 500 msec     (20000 allocations/second)
C++11 - auto_ptr:
Elapsed time: 484 msec     (20661 allocations/second)
C++11 - shared_ptr:
Elapsed time: 1157 msec     (8643 allocations/second)
C++11 - unique_ptr:
Elapsed time: 484 msec     (20661 allocations/second)

除了共享_ptr以外的所有内容都具有相同的速度。shared_ptr必须分配一些锁定构建体(MUTEX),因为它的线程是安全的,涉及参考countnig和neak_ptr分配。

第二,您的方法论是有缺陷的,每个分配后都进行交易,然后进行相同大小的分配。由于分配指针没有用于任何东西,因此编译器可能只能优化所有内容。

,顶级内存管理器也很可能可以从堆里快速地给返回指针,因为它刚刚被交给了相同尺寸的指针。它永远不必回到下部堆即可增加堆。