我试图提高当前程序的速度,该程序记录来自多个传感器的数据,但具体的一部分非常慢。
在这部分中,我将信号数据存储在大小为50的整数数组中,并提取最大值和最小值以获得幅度的(粗略)指示。这是针对每秒3个传感器完成的,但是对阵列进行排序以获得最小值和最大值需要很长时间。
我的第一个想法是将数据存储在排序列表中,但是如何跟踪必须删除的最后一个信号点是什么?
当前代码:
static int movement[AD_SENSORS][AD_MOVEMENT_SIZE];
static int totals[AD_SENSORS];
int movement_sorted[AD_MOVEMENT_SIZE];
int difference = 0;
static unsigned int i; // Movement index
int k = 0;
//Update positions
if (++i>(AD_MOVEMENT_SIZE-1)){i=0;} //increment index of movement array
//Initialise signal value
struct tty_data_t *Current = NULL;
Current = head_tty;
//Add signals to movement array
while (Current != NULL){
totals[Current->ID] = totals[Current->ID] - movement[Current->ID][i];
movement[Current->ID][i] = Current->AD_signal;
totals[Current->ID] = totals[Current->ID] + movement[Current->ID][i];
Current->AD_average = totals[Current->ID] / AD_MOVEMENT_SIZE;
for (k = 0; k<AD_MOVEMENT_SIZE; k++){
movement_sorted[k] = movement[Current->ID][k];
}
qsort (movement_sorted, AD_MOVEMENT_SIZE, sizeof(int), Compare);
Current->AD_amplitude = movement_sorted[AD_MOVEMENT_SIZE-1] - movement_sorted[0];
difference += movement_sorted[AD_MOVEMENT_SIZE-1] - movement_sorted[0];
Current = Current->next;
}
g_movement = difference;
答案 0 :(得分:1)
排序五十个元素不应该花很长时间,它应该能够在三分之一秒内完成。
但是,您可能实际上不需要进行排序。假设您有最后50个元素的滚动数组,您只需要调整min
和max
(以及与它们匹配的元素数mincount
和maxcount
)在有限的情况下。我将为您提供最大值的步骤,但也可以轻松地将逻辑复制到最小值。这些都是相互排斥的情况,应按给定的顺序进行检查(您发现的第一场比赛排除了其后的所有其他比赛):
max
设置为该元素,并将maxcount
设置为1。max
相同,只需在maxcount
中添加一个。max
,请将max
设置为该值,并将maxcount
设置为1。
如果您要移除的值与max
相同且maxcount
大于1,则只需递减maxcount
。max
(此时maxcount
必须为1),请扫描列表中的项目以重新计算新{{1}并相应地设置计数。唯一的可能代价高昂的选项是最后一个,我希望它很少发生。在任何情况下,每次迭代搜索一个大小为50的数组并进行几次比较仍然应该非常快。
并且不要太关注性能。即使是每秒100个读数的8个传感器,每个也只能提供800个数据点。由于数据集很小,排序可能是一个愚蠢的差事,因为按顺序扫描许多项目仍然会非常快(特别是如果您不必每次时间更新滚动数据)。
答案 1 :(得分:1)
如果您要排序只是为了获得最大值和最小值而不是问题中未包含的其他原因,那么您不需要。 您的代码中已经有以下循环:
for (k = 0; k < AD_MOVEMENT_SIZE; k++){
movement_sorted[k] = movement[Current->ID][k];
}
而不是复制数组以对其进行排序(在O(nlogn)
时间内),只需检查每个元素是最大值还是最小值,并在O(n)
时间内获取它们。
int max = INT_MIN;
int min = INT_MAX;
for (k = 0; k<AD_MOVEMENT_SIZE; k++){
if (movement[Current->ID][k] < min) min = movement[Current->ID][k];
if (movement[Current->ID][k] > max) max = movement[Current->ID][k];
}
免责声明:我知道big-O表示法在50个元素的数组中没有说太多,但在更一般的情况下它很重要