浅谈vector中的push_back(无realloc)和 创建vector(n) 后通过下标赋值

在编程过程中,经常都会遇到需要建一个大的vector,并对里面的元素一一顺序求值。此时我们有两种选择

  1. 先reserve(n)后,再一一的push_back

  2. 先建立含n元素的vector,再一一的通过下标为其赋值

那么,这两个方法哪个会更快一些呢?

  • 方法1的好处是再分配内存时直接预留较大的内存即可,而方法2,在建立vector中时,要对其元素一一赋值。

  • 方法2每次直接下标调用即可,不需像方法1每次通过push_back函数为其赋值。

为此,笔者作了如下实验
test1:


 int main() {
    int i=100000;
    for(int j=0;j< i;j++){
        vector<int> sz;
        sz.reserve(10000);
        for(int k=0;k<10000;k++)
            sz.push_back(1);
    }
    return 0;
}

test2:

int main() {
    int i=100000;
    for(int j=0;j<i;j++){
        vector<int> sz(10000);
        for(int k=0;k<10000;k++)
            sz[k]=1;
    }
    return 0;
}

用g++编译后,在ubuntu上测试两个程序的运行时间,发现test1需要20.289s,而test2竟只需要5.435s。且更换数据,多次均是如此。
由此,显然可知,先建立n个元素的vector,再一一用下标取值要快的多。 与n次push_back的时间相比,遍历vector为每个元素的初始化所花时间完全是微不足道的。

故,在已知vector的数据的时候,直接在声明时给出元素个数,是十分明智且效率高的选择。在数据存取时,在同等情况下,可尽量用数组下标存取元素,减少调用push_back的次数。


plus,原因浅究
为什么vector会造成这么慢的访问速度呢?查阅stl源码,发现push_back调用了insert_aux,并在此函数中调用了constructor,copy_backward等函数,其函数的功能也都较简单,但其每一步都要检查是否有效是否发生错误等情况,可见其主要是频繁的检查与其他函数的调用占用了时间,(在调用函数的时候,会需要保留栈,保存变量等情况,在大量push_back时,这些也无形中占用了许多时间,也自然堆积起来使得程序2比程序1慢很多)。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C语言,没有直接的内置容器类型像C++的`vector`。但是,我们可以使用指针和动态分配的内存来模拟二维数组。以下是使用C语言实现`vector<vector<AUDIO_DATA_TYPE>>`的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <limits.h> typedef short AUDIO_DATA_TYPE; typedef struct { AUDIO_DATA_TYPE* data; size_t size; } Vector; typedef struct { Vector* data; size_t size; } VectorVector; void initVector(Vector* vec) { vec->data = NULL; vec->size = 0; } void pushBackVector(Vector* vec, AUDIO_DATA_TYPE value) { vec->data = realloc(vec->data, (vec->size + 1) * sizeof(AUDIO_DATA_TYPE)); vec->data[vec->size] = value; vec->size++; } void initVectorVector(VectorVector* vecVec) { vecVec->data = NULL; vecVec->size = 0; } void pushBackVectorVector(VectorVector* vecVec, Vector vec) { vecVec->data = realloc(vecVec->data, (vecVec->size + 1) * sizeof(Vector)); vecVec->data[vecVec->size] = vec; vecVec->size++; } void freeVector(Vector* vec) { free(vec->data); } void freeVectorVector(VectorVector* vecVec) { for (size_t i = 0; i < vecVec->size; i++) { freeVector(&(vecVec->data[i])); } free(vecVec->data); } void MixSoundsBySimplyAdd(VectorVector allMixingSounds, DWORD RawDataCnt, Vector* __pRawDataBuffer) { typedef int WIDEN_TEMP_TYPE; const WIDEN_TEMP_TYPE AUDIO_DATA_TYPE_MAX = SHRT_MAX; const WIDEN_TEMP_TYPE AUDIO_DATA_TYPE_MIN = SHRT_MIN; WIDEN_TEMP_TYPE Sum = 0; for (int i = 0; i < RawDataCnt; ++i) { Sum = 0; for (int wavNum = 0; wavNum < allMixingSounds.size; ++wavNum) { Sum += allMixingSounds.data[wavNum].data[i]; } if (Sum > AUDIO_DATA_TYPE_MAX) Sum = AUDIO_DATA_TYPE_MAX; else if (Sum < AUDIO_DATA_TYPE_MIN) Sum = AUDIO_DATA_TYPE_MIN; pushBackVector(__pRawDataBuffer, AUDIO_DATA_TYPE(Sum)); } } int main() { VectorVector allMixingSounds; initVectorVector(&allMixingSounds); // 添加数据到allMixingSounds Vector vec1; initVector(&vec1); pushBackVector(&vec1, 1); pushBackVector(&vec1, 2); pushBackVector(&vec1, 3); pushBackVectorVector(&allMixingSounds, vec1); Vector vec2; initVector(&vec2); pushBackVector(&vec2, 4); pushBackVector(&vec2, 5); pushBackVector(&vec2, 6); pushBackVectorVector(&allMixingSounds, vec2); // 创建输出缓冲区 Vector rawDataBuffer; initVector(&rawDataBuffer); // 调用MixSoundsBySimplyAdd函数 MixSoundsBySimplyAdd(allMixingSounds, 3, &rawDataBuffer); // 输出结果 for (int i = 0; i < rawDataBuffer.size; i++) { printf("%d ", rawDataBuffer.data[i]); } printf("\n"); // 释放内存 freeVectorVector(&allMixingSounds); freeVector(&rawDataBuffer); return 0; } ``` 以上代码演示了如何使用指针和动态分配的内存来模拟`vector<vector<AUDIO_DATA_TYPE>>`。你可以根据自己的需求进行修改和调整。请注意,在使用完后,需要对动态分配的内存进行释放,以避免内存泄漏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值