在给所有的文档打完分以后,接下来,我们就要完成排序的工作了。一般来说,我们可以使用任意一种高效的排序算法来完成排序,比如说,我们可以使用快速排序,它排序的时间代价是 O(n log n)。但是,我们还要考虑到,搜索引擎检索出来结果的数量级可能是千万级别的。在这种情况下,即便是 O(n log n) 的时间代价,也会是一个非常巨大的时间损耗。
那对于这个问题,我们该怎么优化呢?
其实,你可以回想一下,我们在使用搜索引擎的时候,一般都不会翻超过 100 页(如果有兴趣,你可以试着翻翻,看 100 页以后搜索引擎会显示什么),而且,平均一页只显示 10 条数据。也就是说,搜索引擎其实只需要显示前 1000 条数据就够了。因此,在实际系统中,我们不需要返回所有结果,只需要返回 Top K 个结果就可以。这就是许多大规模检索系统应用的的 Top K 检索 了。而且,我们前面的打分过程都是非常精准的,所以我们今天学习的也叫作 精准 Top K 检索。
当然还有非精准的 Top K 检索,这里先卖个关子,我会在下一讲详细来讲。
那再回到优化排序上,由于只需要选取 Top K 个结果,因此我们可以使用堆排序来代替全排序。这样我们就能把排序的时间代价降低到 O(n) + O(k log n)(即建堆时间 + 在堆中选择最大的 k 个值的时间),而不是原来的 O(n log n)。举个例子,如果 k 是 1000,n 是 1000 万,那排序性能就提高了近 6 倍!这是一个非常有效的性能提升。