用memcpy,memmove或std:copy替换For循环?

时间:2015-03-27 14:00:32

标签: c++

我有移位功能,我不断发送新数据点,它会将我的点移动偏移量为1.这是为了实现一个"图形移位"其中点代表图表上的点。

移位功能如下:

void Chart_Buffer::ShiftData()
{
    for(int index = 0; index < (_channel_Samples - 1); ++index)
    {
      _sample_Points[index].y = _sample_Points[index + 1].y;
    }
  return;
}

这个问题是它正在运行一个包含多达800个数据点的大量阵列,并且每次添加的每个新数据点都会这样做,所以我想看看我是否可以通过移动所有值来优化此过程偏移量为1而不通过for循环。我查看了memcopy,memmove和std :: copy的实现,但我无法弄清楚如何将它们用于我的目的。

基本上,如果我在数组中有元素0-799,我想将元素1-799移位1,这样我就有0-798,然后只需将新元素添加到数组中。

修改:_sample_PointstagPOINT类型,具有以下结构:

typedef struct tagPOINT
{
    LONG  x;
    LONG  y;
} POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;

4 个答案:

答案 0 :(得分:1)

看起来您正在寻找std::deque。它是一个双端队列,这意味着你可以从后面弹出一个元素并在前面推动。

如果你要找的是按照一定的顺序保持数组的元素,这将有助于你做到这一点。

现在,如果你还想让它们在内存上连续存在,那么你可以这样做:

memmove(array+1, array, sizeof(element)*(array_size-1));
array[0] = new_element;

答案 1 :(得分:1)

如果没有比你现在做的更少的操作,你不能这样做,无论你拼写所有这些还是你调用算法。问题是操作你最初描述的是,它不是移动数据,而是移动数据的部分(只有y坐标)但保持另一半原样。

如果您不想拼出该操作,可以采用类似于 id256 的答案的方式使用transform算法,但我不确定不管这是否真的有所改进,问题中的循环比transform ...

更容易和更清晰

答案 2 :(得分:1)

如果您的代码重构是可接受的,那么您也可以放弃tagPOINT而不是拥有一个_sample_Points,而是拥有两个数组,一个用于x和一个用于y。然后你可以memmove() y的数组LONG _sample_Points_x[DIMENSION]; LONG _sample_Points_y[DIMENSION]; void Chart_Buffer::ShiftData() { memmove(_sample_Points_y, _sample_Points_y + 1, (DIMENSION-1) * sizeof _sample_Points_y[0]); } 。像:

{{1}}

答案 3 :(得分:1)

如果不知道你在_sample_Points做了什么,很难给出一个坚定的答案。但我相信我可以坚定地说,将数组中的每个元素复制一个是一种昂贵的方法。

在最好的情况下:您只需要访问数组的前面并添加到数组的后面。如果是这种情况,那么您正在描述queue。< / p>

  • 要在queue使用后面添加新元素:push
  • 要检查前部元素,请使用:front
  • 要“将所有内容复制下来”(只需删除前面元素),请使用:pop

否则您将遇到以下情况:您需要随机访问数组。如果是这种情况,您仍然可以从deqeu获得更好的性能。

  • 要在deque使用后面添加新元素:push_back
  • 要检查前部元素,请使用:front
  • 要“将所有内容复制下来”(只需删除前面元素),请使用:pop_front

因此,如果您为queue _sample_Points使用Chart_Buffer::ShiftData,则可以用_sample_Points.pop()替换。

如果您使用deque _sample_Points Chart_Buffer::ShiftData,则_sample_Points.pop_front()可以替换为{{1}}。