Algorithm 这个线性搜索实现真的有用吗?
在中,我发现了这个有趣的线性搜索实现(实际上是我的Java实现;-): 它基本上使用了sentinel,这是搜索的值,因此您总是可以找到值,而不必检查数组边界。最后一个元素存储在一个temp变量中,然后将sentinel放置在最后一个位置。当找到该值时(记住,由于sentinel,它总是被找到),原始元素将被还原,并且索引将被检查,如果它表示最后一个索引并且与搜索到的值不相等。如果是这种情况,则返回-1(不包含),否则返回索引 虽然我发现这个实现非常聪明,但我想知道它是否真的有用。对于小型阵列,它似乎总是较慢,而对于大型阵列,只有在找不到该值时,它似乎才较快。有什么想法吗 编辑Algorithm 这个线性搜索实现真的有用吗?,algorithm,Algorithm,在中,我发现了这个有趣的线性搜索实现(实际上是我的Java实现;-): 它基本上使用了sentinel,这是搜索的值,因此您总是可以找到值,而不必检查数组边界。最后一个元素存储在一个temp变量中,然后将sentinel放置在最后一个位置。当找到该值时(记住,由于sentinel,它总是被找到),原始元素将被还原,并且索引将被检查,如果它表示最后一个索引并且与搜索到的值不相等。如果是这种情况,则返回-1(不包含),否则返回索引 虽然我发现这个实现非常聪明,但我想知道它是否真的有用。对于小型阵列,
原始的实现是用C++编写的,所以可以有所作为。
< P>一个前哨搜索回到Knuth。它的价值在于将循环中的测试数量从两个(“键匹配吗?我在末尾吗?”)减少到一个 是的,它很有用,因为它可以通过消除条件分支预测失误,大大减少中等大小无序数组的搜索时间。这还减少了此类数组的插入时间(OP未显示代码),因为您不必订购这些项目 如果有序项的数组较大,则二进制搜索会更快,但代价是插入时间较长,以确保数组有序 对于更大的集合,哈希表将是最快的真正的问题是阵列大小的分布是什么?哨兵搜索可以追溯到Knuth。它的价值在于将循环中的测试数量从两个(“键匹配吗?我在末尾吗?”)减少到一个 是的,它很有用,因为它可以通过消除条件分支预测失误,大大减少中等大小无序数组的搜索时间。这还减少了此类数组的插入时间(OP未显示代码),因为您不必订购这些项目 如果有序项的数组较大,则二进制搜索会更快,但代价是插入时间较长,以确保数组有序 对于更大的集合,哈希表将是最快的
真正的问题是阵列大小的分布是什么?似乎并不特别有用。这里的“创新”仅仅是通过将迭代测试与匹配测试相结合来摆脱迭代测试。如今,现代处理器在迭代检查上花费的时间为0(所有的计算和分支都与匹配测试代码并行完成)
在任何情况下,二进制搜索在大型数组上都比这段代码好,在小型数组上也比得上。线性搜索非常有用。似乎不是特别有用。这里的“创新”仅仅是通过将迭代测试与匹配测试相结合来摆脱迭代测试。如今,现代处理器在迭代检查上花费的时间为0(所有的计算和分支都与匹配测试代码并行完成)
在任何情况下,二进制搜索在大型数组上都比这段代码好,在小型数组上也比得上。线性搜索是如此的简单。它不是线程安全的,例如,在第一个线程将
a[high]
更改为key
后,通过第二个线程开始,您可能会丢失a[high]
值,因此将key
记录到tmp
,并在第一个线程恢复a[high]后完成
恢复到其原始值。第二个线程将a[high]
恢复到它第一次看到的状态,这是第一个线程的键
它在java中也没有用处,因为JVM将在数组中包含边界检查,所以while循环检查数组是否没有结束。它不是线程安全的,例如,您可能会丢失a[high]
值通过在第一个线程将a[high]
更改为key
后开始第二个线程,因此将key
记录为tmp
,并在第一个线程将a[high]
恢复为其原始值后结束。第二个线程将a[high]
恢复到它第一次看到的状态,这是第一个线程的键
它在java中也没有用处,因为JVM将在数组中包含边界检查,所以while循环检查数组是否没有结束。另请参阅“在非洲寻找老虎”笑话。
Punchline=一位经验丰富的程序员在开罗放置一只老虎,以便搜索终止。另请参见“在非洲寻找老虎”的笑话。
Punchline=一个有经验的程序员在开罗放了一只老虎,这样搜索就终止了。你会注意到这会增加速度吗?没有
你会注意到缺乏可读性吗?对
您是否会注意到可能导致并发问题的不必要的数组变异?对
过早优化是万恶之源。你会注意到由此带来的速度提升吗?没有
你会注意到缺乏可读性吗?对
您是否会注意到可能导致并发问题的不必要的数组变异?对
过早优化是万恶之源。是的,因为while循环与标准搜索相比没有两个比较
它的速度是原来的两倍。在Knuth第3卷中作为优化给出了它。是的,因为while循环没有2个与标准搜索相反的比较
它的速度是原来的两倍。在Knuth第三卷中作为优化给出了它。“它似乎总是比较慢…更快…”相对于什么替代方案?Sry,我的意思是与标准相比
public static int linearSearch(int[] a, int key) {
int high = a.length - 1;
int tmp = a[high];
// put a sentinel at the end of the array
a[high] = key;
int i = 0;
while (a[i] != key) {
i++;
}
// restore original value
a[high] = tmp;
if (i == high && key != tmp) {
return NOT_CONTAINED;
}
return i;
}