标准向量性能/替代

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 at std::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 实现会在您调整矢量大小时减少矢量的容量,但我认为这不是标准的要求。 编辑:标准包括要求当您调整到当前容量以下时迭代器不会失效,这保证了容量不会减少。

【讨论】:

谢谢马克,我试试看。

以上是关于标准向量性能/替代的主要内容,如果未能解决你的问题,请参考以下文章

Java HashMap 性能优化/替代

如何用MATLAB将特征向量标准化

ALINK(二十):数据处理数值型数据处理向量标准化 VectorNormalizeBatchOp/向量标准化训练 VectorStandardScalerTrainBatchOp /向量

将数字向量转换为标准单位向量的函数

推力::主机向量和标准::向量有啥区别?

标准 C# DataGrid 的免费替代品?