标准向量性能/替代
Posted
技术标签:
【中文标题】标准向量性能/替代【英文标题】:std vector performance/alternative 【发布时间】:2016-11-07 21:51:58 【问题描述】:我必须临时处理和存储数据。目前我使用std::vector::push_back
添加数据和std::vector::erase
在达到最大元素时擦除元素。我的问题是我必须处理大量数据,并且当达到最大数量时,擦除似乎会影响性能。所以我决定每 y 毫秒添加一次数据并删除 x 个元素,作为优化。首先,我还在向量中保留了一定数量。我使用向量是因为我需要 const double *std::vector<T>::data()
函数将数据传递到其他地方,而且我不能进行任何转换/复制或任何事情。它必须要快。
std::vector<double> data;
size_t max; // there are millions of elements, e.g. 2000000
data.reserve(max);
// happens every x microseconds
void receive(double val)
data.push_back(val);
// timed every x ms
void update()
if (data.size() > max)
data.erase(data.begin(),data.end()+(data.size()-max));
我的问题是:如何提高效率?通过使用另一个容器?那么是否仍然可以将容器转换为const double *
?
我刚刚意识到,我总是在这个设置下超过最大值,这可能是性能下降的原因吗?下面的代码能解决这个问题吗?
if (data.size() > max*0.8)
data.erase(data.begin(),data.begin()+(data.size()-max*0.8));
提前致谢!
【问题讨论】:
Look atstd::deque
我做了,但它没有 const T *data() 函数,或者是吗?
您的要求让您陷入了困境。对于连续数据,您需要偶尔移动数据。
看来你在要求不可能的事情......如果你的要求是你有一个单一的平面缓冲区,那么没有办法从中间擦除而不向下移动上面的所有元素,这需要时间
我预计复制数据大约 10 次比复制一次需要更长的时间
【参考方案1】:
正如我在 cmets 中所说,您的要求确实让您陷入困境。我所知道的唯一为您提供连续数据的容器是 std::vector
。
std::vector
有两种浪费时间的行为。第一个是当你尝试push_back
在一个已经处于其保留容量的向量上时;必须分配一个新缓冲区,并将旧缓冲区内容复制到新缓冲区。您可以通过在达到容量之前擦除元素来轻松避免这种情况。第二个是从向量末端以外的任何地方擦除;这需要将元素从缓冲区中的旧位置复制到新位置。 这部分是不可避免的。您唯一的选择是尽可能少地执行此操作,一次擦除尽可能多的元素。
这是一个为您提供两种条件的模组:
void receive(double val)
static const size_t drop_size = max / 2;
if (data.size() == data.capacity())
data.erase(data.begin(), data.begin() + drop_size);
data.push_back(val);
这会在缓冲区变满时丢弃一部分数据。我随意选择了 max/2,但您可以调整该阈值以满足您的实际要求。
一个好的编译器会在erase
期间优化元素的复制,但是你有可能用memcpy
做得更好。在这种情况下,您可以将 erase
替换为以下内容:
memcpy(&(data[0]), &(data[drop_size]), sizeof(double) * (data.size() - drop_size));
data.resize(data.size() - drop_size);
在您决定使用它之前,您绝对应该对此进行基准测试。 我不知道有任何 编辑:标准包括要求当您调整到当前容量以下时迭代器不会失效,这保证了容量不会减少。vector
实现会在您调整矢量大小时减少矢量的容量,但我认为这不是标准的要求。
【讨论】:
谢谢马克,我试试看。以上是关于标准向量性能/替代的主要内容,如果未能解决你的问题,请参考以下文章
ALINK(二十):数据处理数值型数据处理向量标准化 VectorNormalizeBatchOp/向量标准化训练 VectorStandardScalerTrainBatchOp /向量