什么时候使用 List<T>.BinarySearch?
when to use List<T>.BinarySearch?
.NET 中的通用 List<T>
有一个 BinarySearch()
方法。 BinarySearch()
是一种搜索大型数据集的高效算法。我想我读到过,如果世界上的每个人都列在 phone 一本书中,那么二进制搜索可以在 35 步内找到任何人。在什么时候应该在 List
上使用 BinarySearch()
而不是使用带 lambda 的标准 .Where
子句?在从 Where
切换到 BinarySearch
之前,数据集应该有多大?还是 Where
已经在幕后使用了二进制搜索?
At what point should a BinarySearch()
be used on a List as opposed to using the standard Where
clause with a lambda?
只要列表相对于您搜索的值进行排序,无论大小如何,BinarySearch
都会(平均)为您提供比 Where
更好的性能。
如果列表是无序的,或者顺序与您要查找的值不对应(您不能使用二进制搜索在 phone 书中通过 first name) then BinarySearch
不会给你正确的结果。
请注意,它只有 returns 一个索引 ,而 Where
将为您提供 所有匹配项 条件,但如果有重复项,您可以在找到的元素的任一侧进行搜索(BinarySearch
为您提供 one 匹配的索引,不一定是 first 索引)。
显然列表越大,BinarySearch
给您的改进就越大。
does Where
already use a binary search behind the scenes?
否 - 它按物理顺序遍历列表。
When to use List<T>.BinarySearch
?
如您在 documentation manual 中所读:
Searches the entire sorted List<T>
for an element using the default comparer and returns the zero-based index of the element.
此外,它只能用于匹配给定的 元素,而不是谓词,因为通用谓词会破坏顺序约束。
因此必须对列表进行排序,可以通过默认比较器,也可以通过给定比较器:
public int BinarySearch(T item) //default comparator
public int BinarySearch(T item, IComparer<T> comparer) //given comparator
算法运行 O(log n) 时间而 where
子句运行 O(n) 时间,这意味着在实践中它几乎总是优于第二个(除非该元素很可能位于列表的前面)。
Or does .Where
already use a binary search behind the scenes?
不,以后不能。 A List<T>
并不总是排序的。首先检查列表是否已排序,或者对列表进行排序需要计算 O(n) 或 O(n log n)分别与线性搜索相同甚至更昂贵。换句话说,首先检查列表是否已排序,然后 - 如果是这种情况 - 执行二进制搜索将比执行线性搜索更昂贵。线性搜索可以处理无序列表和谓词,但成本要高得多。
.NET 中的通用 List<T>
有一个 BinarySearch()
方法。 BinarySearch()
是一种搜索大型数据集的高效算法。我想我读到过,如果世界上的每个人都列在 phone 一本书中,那么二进制搜索可以在 35 步内找到任何人。在什么时候应该在 List
上使用 BinarySearch()
而不是使用带 lambda 的标准 .Where
子句?在从 Where
切换到 BinarySearch
之前,数据集应该有多大?还是 Where
已经在幕后使用了二进制搜索?
At what point should a
BinarySearch()
be used on a List as opposed to using the standardWhere
clause with a lambda?
只要列表相对于您搜索的值进行排序,无论大小如何,BinarySearch
都会(平均)为您提供比 Where
更好的性能。
如果列表是无序的,或者顺序与您要查找的值不对应(您不能使用二进制搜索在 phone 书中通过 first name) then BinarySearch
不会给你正确的结果。
请注意,它只有 returns 一个索引 ,而 Where
将为您提供 所有匹配项 条件,但如果有重复项,您可以在找到的元素的任一侧进行搜索(BinarySearch
为您提供 one 匹配的索引,不一定是 first 索引)。
显然列表越大,BinarySearch
给您的改进就越大。
does
Where
already use a binary search behind the scenes?
否 - 它按物理顺序遍历列表。
When to use
List<T>.BinarySearch
?
如您在 documentation manual 中所读:
Searches the entire sorted
List<T>
for an element using the default comparer and returns the zero-based index of the element.
此外,它只能用于匹配给定的 元素,而不是谓词,因为通用谓词会破坏顺序约束。
因此必须对列表进行排序,可以通过默认比较器,也可以通过给定比较器:
public int BinarySearch(T item) //default comparator
public int BinarySearch(T item, IComparer<T> comparer) //given comparator
算法运行 O(log n) 时间而 where
子句运行 O(n) 时间,这意味着在实践中它几乎总是优于第二个(除非该元素很可能位于列表的前面)。
Or does
.Where
already use a binary search behind the scenes?
不,以后不能。 A List<T>
并不总是排序的。首先检查列表是否已排序,或者对列表进行排序需要计算 O(n) 或 O(n log n)分别与线性搜索相同甚至更昂贵。换句话说,首先检查列表是否已排序,然后 - 如果是这种情况 - 执行二进制搜索将比执行线性搜索更昂贵。线性搜索可以处理无序列表和谓词,但成本要高得多。