搜索数组中结果的最快方法

时间:2016-10-14 20:16:22

标签: algorithm

我有一个算法来搜索包含64个字节值的数组,我想找到一个4位值,看看它在数组中出现了多少次。例如,数组中的第一个元素可能是10101010,4位值是1010,其中只计算一次。如果下一个元素是10000000,那么这将被计为0.如果我们的4位结果存在,那么很容易遍历数组中的所有元素并检查每个元素但是有更快的方法吗?

1 个答案:

答案 0 :(得分:2)

precompute:
- 4bit key offset by 0bit
- 4bit key offset by 1bit
- 4bit key offset by 2bit
- 4bit key offset by 3bit

- 4 bit mask offset by 0bit
- 4 bit mask offset by 1bit
- 4 bit mask offset by 2bit
- 4 bit mask offset by 3bit

for each byte in bytes:
  for each offset:
    mask out bytes we care about
    check if it matches our precomputed key
  • 由于我们不看的任何项目都可能匹配,我们必须查看所有项目,至少O(n)
  • 由于只查看一次所有项目就足够了,所以没有理由使用非线性算法。
  • 由于它总共只有64个值,因此高度优化的SIMD指令可能不值得麻烦。它不太可能提高性能。

通过将键一次向左移位一位,并通过在掩码中将4个相关位设置为1来完成键和掩码的预计算。

match = (bytes[i] & (0x0F << offset)) == (key << offset)
某些key和每个偏移0-3

。由于(key << offset)(0x0F << offset)将在每四个循环中重复使用,因此预先计算四个值并展开循环将会更快。您的编译器可能会为您执行此操作,但如果没有,请按以下步骤操作:

matches = 0
for (int i = 0; i < 64; i += 4) {
    const mask0 = 0x0F << 0
    const key0 = key << 0
    match0 = (bytes[i+0] & mask0) == key0

    const mask1 = 0x0F << 1
    const key1 = key << 1
    match1 = (bytes[i+1] & mask1) == key1

    ...

    matches += match0 + match1 + match2 + match3
}