我目前工作的地方我遇到性能问题的嵌入式设备项目。 谱已经位于我想消除的O(N)的操作。
我基本上有两种阵列int A[N]
和short B[N]
在条目A
是独一无二的,由外部约束排序。 最常见的操作是检查是否一个特定的值a
出现在A[]
不太频繁,但仍是常见的改变的一个元素A[]
新价值是毫无关系的一个值。
由于最常见的操作是查找,这其中B[]
进来,它是指数在排序后的数组A[]
使得A[B[i]] < A[B[j]]
当且仅当i<j
这意味着,我可以找到值A
使用二进制搜索。
当然,当我更新A[k]
,我必须要找到k
在B
并将其移动到新位置,以维持搜索顺序。 由于我知道的新旧值A[k]
,这只是一个memmove()
的一个子集的B[]
的新老位置之间k
。 这是O(N)的操作,我需要修复; 自的新旧值A[k]
基本上是随机的我上移动平均约N / 2 N / 3个元素。
我看着std::make_heap
使用[](int i, int j) { return A[i] < A[j]; }
[](int i, int j) { return A[i] < A[j]; }
作为谓词。 在这种情况下,我可以很容易地使B[0]
指向的最小元素A
,以及更新B
现在是一个便宜的为O(log N)重新平衡操作。 不过,我一般不需要的最小值,我需要找到,如果任何给定的值存在。 这就是现在O(N日志N)在搜索B
。 (我的N个元素的一半是在堆深度日志N,在(日志N)-1四分之一等),这是在哑O(N)直接在搜索没有改善A
。
考虑到std::set
有O(日志N)的插入和查找,我会说,它应该可以在这里得到相同的性能更新和查找。 但我怎么做呢? 我是否需要另一份订单B
? 不同的类型?
B
目前是short [N]
因为A
和B
一起是我的CPU高速缓存的大小,和我的主存储器是慢了很多。 从6要去* N 8 * N个字节就不会很好,但如果我发现还是可以接受的,并更新到O(日志N)两种。