std::vector<void*>::保留 O(1) 时间操作的参数是什么?
For what argument is std::vector<void*>::reserve an O(1) time operation?
我想知道以下问题的大致答案:
int n;
...
std::vector<void*> vectorOfPointers;
vectorOfPointers.reserve(n);
在 0 (1)中,上述程序最多运行到哪个数字n ?让我们假设对于一台运行32位Ubuntu和3gb内存的笔记本电脑,不运行任何其他程序。是几万、几千还是几百万?一个人需要知道什么信息才能回答这样的问题?有没有一种不用实验就能知道的方法?
我从来没有研究过操作系统,但在我的想象中,操作系统分配内存只需要2步。它决定了块开始的指针和块结束的指针。情况可能会更加复杂,因为系统可能必须进行清理,以便获得足够大的内存块。但是,如果我们假设系统只运行这一个程序,我们如何估计所需的时间?除了内存碎片之外,还有其他方面需要考虑吗?
编辑:对不起,我没有把我的问题说清楚。需要注意的是,在调用reserve之前vector是空的,因此不需要复制数据。从c++的角度来看,代码占用O(1)
时间(它在当前容器的大小中是线性的,在您的情况下始终为零)。
现在,看起来你的问题实际上是关于分配m
字节内存的复杂性。这恐怕是没有说明的。
有关进一步的讨论,请参见内存分配的时间复杂度
在前面的问题上再补充一点,这里有几个层次的复杂性:
- 首先,
malloc()
需要维护其内部数据结构。这样做的复杂性没有指定,但是人们希望malloc(m)
不会占用Θ(m)
的时间。然而,复杂性很可能取决于其他因素,例如内存碎片。其次,malloc()
可能需要从操作系统请求额外的内存。在这里,期望操作系统对它分配的每个内存页做一些事情(例如擦除它,这样你就不会看到其他人的机密数据)并不是不合理的。如果发生这种情况,操作确实是Θ(m)
。
使用reserve()
时不能依赖于0(1)复杂度。
复杂性(cf cppreference)容器大小线性
基本上,新内存的分配是在常数时间内,但是你还需要将旧元素从以前的内存复制到新的内存中(因此线性复杂性)。
因此,在空向量上,保留可能有一个常数时间,但我不确定标准是否明确说明了这一点。所以这可能取决于底层的实现(即使我没有看到任何不这样做的理由)。
唯一的O(1)
我能想到的std::vector::reserve()
是当n <= capacity()
,这意味着reserve()
不做任何事情。
相关文章:
- C++为构建时间获取QDateTime的可靠方法
- 在SQLITE数据库中写入记录需要花费大量时间.如何提高刀片操作效率?
- 以毫秒级精度对日期和时间进行操作
- 如何计划在将来时间运行的操作
- 程序执行基本操作所花费的总时间
- 从长时间中提取每个单词的钻头操作
- std::list c++是连续的,那么在序列中的任何位置插入和擦除操作都需要恒定的时间
- 如何使生成的线程拖延足够长的时间以使生成线程执行某些操作
- 在 QThread 中运行长时间操作并将信号发送到主线程仍会冻结 UI
- 在C++中的代码中指定的某个等待时间后执行某个操作
- 测试一个操作在Qt中花费多少时间的最简单方法
- 汇编操作的时间
- 具有c++标准规定的时间复杂度的操作能否动态分配内存?
- 是否有一种可编程的方法来估计CPU执行fp操作所需的时间
- Boost:如何处理依赖于时间的线程操作
- 具有常数时间操作的数据结构
- 为什么ctime clock()在同一个程序对同一个操作调用两次时给出不同的时间?
- 获取当前线程id的操作时间昂贵
- 计算c++中操作之间的时间长度
- std::vector<void*>::保留 O(1) 时间操作的参数是什么?