考虑到p <- plot_ly(grph$try1,
x = ~Inputs,
y = ~Inputs2,
type = 'bar',
text = ~round(Inputs2, 2),
textposition = 'auto', name = 'Inputs2', marker = list(color = 'rgb(204,204,204)')) %>%
add_trace(y = ~Inputs3,
text = ~round(Inputs3, 2),
textposition = 'auto',
name = 'Inputs3',
marker = list(color = 'rgb(49,130,189)')) %>%
layout(title = "Plot", barmode = 'group', yaxis = list(title = "Count"))
的大小和容量可以是任意的,将其大小更改为0并将容量至少更改为N(给定数字)的最佳实践是什么?
我的直接想法是:
std::vector
但是我注意到了
不能保证会发生重新分配,向量容量为 不保证更改(调用std::vector::clear时)。
所以我想知道当原始容量大于给定N时如何避免重新分配?
答案 0 :(得分:4)
什么是将其大小更改为0并将容量更改为N(给定数字)的最佳实践?我的直接想法是:...
您的直接想法是正确的,也是最简单的选择。尽管reserve
有点古怪,但将容量更改为更大或等于给定的数字;不能保证相等(但是如果以前的容量较小,我测试过的所有实现都确实会分配给定的数量)。
所以我想知道当原始容量大于给定N时如何避免重新分配?
通过使用已选择在调用clear
时不释放内存的标准库实现(即,任何符合标准的实现,如答案here所示)。
另一种保证方法(尽管看起来很必要,尽管cplusplus.com上的措词很弱,但上述保证没有必要)没有重新分配(在N > t.capacity()
情况下):由于向量包含简单的整数,并且您似乎知道有多少个元素(如您所知要保留),您可以简单地调用t.resize(N)
(在大小较大的情况下删除多余的元素)而无需清除向量,然后继续覆盖现有元素,而不是推送新元素。
当然,这意味着您将无法观察已被覆盖的元素数量,因此该方法不适用于所有用例。如果只想用一个简单的循环填充向量就可以了。
如果新大小可能大于旧大小,并且您希望不过度分配,则可能需要在调整大小之前保留。这是因为大多数实现都在储备中分配了准确的数量(如我所述),但在调整大小时使用了乘法策略(就我所知,这些行为都不能保证,但是我使用的实现与这种行为是一致的)。 / p>
答案 1 :(得分:3)
最好的方法可能是您当前的代码。
不幸的是,该标准允许实现只具有容量只能增长的容器。在这种情况下,您的代码将仅保证容量为至少N。如果初始容量小于N,则将发生重新分配,而如果容量大于N,则将不会发生任何事情。之所以采用该标准,是因为C ++ 17的草案4659在[vector.capacity](强调我的)上表示:
void reserve(size_type n);
...
3效果:一条指令,该指令将向量的计划大小更改通知向量,以便它可以管理存储 相应地分配。 在reserve()之后,capacity()大于或等于reserve的参数,如果 重新分配发生;并等于以前的Capacity()值。重新分配发生 此时且仅当当前容量小于reserve()的参数时。
和
void shrink_to_fit();
...
8效果:shrink_to_fit是无约束请求,用于将Capacity()减小为size()。 [注意:要求 是不具有约束力的,以允许进行特定于实现的优化。 —尾注]它没有 增加Capacity(),但可能通过引起重新分配来减少Capacity()。
您无法保证容量恰好为N。相反,您的代码保证,如果初始容量大于N in,则将保持不变,并且不会发生重新分配。
编辑:至少从C ++ 11起(n3337草稿),此行为是稳定的
答案 2 :(得分:0)
注意:此答案回答了以下问题:
制作std :: vector容量= N且尺寸= 0的最佳方法是什么?
和
将大小更改为0,将容量更改为N(给定数字)的最佳做法是什么?
发布此答案后,添加了对“> = N”的更改以及避免重新分配的附加要求。
该标准没有提供任何保证的方法来实现这一目标。但是您最好的机会是:
t.clear();
t.shrink_to_fit();
t.reserve(N);
建议第二次调用,以减少与当前大小(此时为0
)相匹配的容量。
再次取决于实施情况的选择,可能有效或无效的一种替代方法是:
t.swap( std::vector<int>{} );
t.reserve(N);