我想一次将元素插入一个环形(循环)缓冲区,并维护一个排列数组,以升序跟踪排序的元素。为此,我调整了“插入排序”算法以使用循环数组索引:
/* sort ringbuf entries with insertion sort algorithm */
void
ringbuf_isort(const ringbuf *rbuf, int *idx)
{
const int n = ringbuf_n(rbuf);
int i, j;
for (i = 1; i < n; i++)
{
int id = idx[i];
double v = rbuf->array[(rbuf->head + id) % rbuf->size];
for (j = i; j > 0; j--)
{
if (rbuf->array[(rbuf->head + idx[j-1]) % rbuf->size] < v)
break;
idx[j] = idx[j-1];
}
idx[j] = id;
}
}
该算法正常工作 -idx
数组包含跟踪其排序状态的缓冲区元素的排列。问题是该算法非常慢,因为循环索引需要模运算,即(head + idx) % size
.
事实上,我发现将环形缓冲区简单地复制到线性数组中并在每次添加元素时使用快速排序算法比使用上面的代码更快。对于线性数组,我已经确认插入排序算法在仅更改单个元素时优于快速排序,所以我希望我能为环形缓冲区找到更好的解决方案。
有谁知道如何优化上面的代码以加速模运算(或完全避免它?)