This is a creation in Article, where the information may have evolved or changed. June 2013
Binary array search several ways of writing (GO)
On children's Day, comparing the performance of Python's built-in dict and binary array search lookups, dict a big lead and some surprises:
- Although Dict is O (1), binary search is O (log n). When n is 1M, log n is also only 20, and intuitively on the front of log n is not very large, theoretically should and O (1) difference is not very big
- In the Python language, binary array search is implemented by hand Python, while dict is C implementation. Python language is much slower than C
So, on the June 2, use the Go language to compare and familiarize yourself with the go language. Binary search is written in several ways:
recusive: Recursive
3-branch: iteration, 2 judgements per iteration, == < (or > ), three branches. When found, exit immediately. Best Case for O (1)
2-branch: iteration, 1 judgements < (or > ), two branches per iteration. The best case is also O (log n)
library: Go standard library sort.Search , which is a generic version of 3 and needs to provide a function to provide > or < basis
2-branch
3 of the idea is interesting, it is calculated for the number to find, if placed in this already ordered array of arrays, subscript is how much. If there is a repetition in the array, the return is the subscript of the first one. Finally, compare the number inside the array, whether it is the key that needs to be searched
func BINARY_SEARCH2(arr []int, Key int) int {Lo, Hi := 0, Len(arr)-1 for Lo < Hi {Mid := (Lo + Hi) / 2if arr[Mid] < Key {Lo = Mid + 1} Else {Hi = Mid}}if Lo == Hi && arr[Lo] == Key {return Lo} Else {return -(Lo + 1)}}
Library
4 is a fun way to achieve search.go:
funcSearch(nint,ffunc(int)bool)int
The go language has no templates, no comparator like Java, no operator overloads, or static types. But this interface does not need these at all and is very versatile (albeit with a bit of performance loss)
3-branch and Recusive
1 and 2 are conventional solutions.
//Recusivefunc Binary_search0(arr []int, Key int) int {return Binary_search_(arr, 0, Len(arr), Key)}func Binary_search_(arr []int, begin, End, Key int) int {if begin > End {return -1}Mid := (begin + End) / 2if arr[Mid] == Key {return Mid} Else if arr[Mid] > Key {return Binary_search_(arr, begin, Mid-1, Key)} Else {return Binary_search_(arr, Mid+1, End, Key)}}//3-branchfunc Binary_search(arr []int, Key int) int {Lo, Hi := 0, Len(arr)-1 for Lo <= Hi {Mid := (Lo + Hi) / 2if arr[Mid] == Key {return Mid} Else if arr[Mid] < Key { //Search Upper SubarrayLo = Mid + 1} Else {Hi = Mid - 1}}return -(Lo + 1)}
Performance comparison
Randomly generate 2k to 500k int, make 1500 queries, record the time. and contrast it with the built-in map.
- The map is still the quickest, but not as fast as python.
- The Go standard library is very versatile and the slowest
- With the increase in the number of item, 2-branch relative to the advantages of 3-branch obvious: thanks to the increase in the number of possible iterations (not found on the return), but each 2 comparisons, 3 branch + 1 Compare 2 branch. The JDK is java.util.Arrays.binarySearch with a 3-branch version, which may have an advantage over a large quantity (less than 2k), or other considerations
Recursive, looks OK, but easy to write, not easy to make mistakes. Very good
The code BINARY_SEARCH.GO and draws the result into a better-looking bar chart binary_hash_go.py
PS: this weekend in addition to gather with friends, for girlfriend's nephew to buy toys, the rest is toss binary search.