1
0
mirror of https://github.com/golang/go synced 2024-11-26 16:46:58 -07:00

all: faster midpoint computation in binary search

On my machine (3.1 GHz Quad-Core Intel Core i7, macOS 10.15.7 10.15.7), go 1.15.6

benchstat:
name          old time/op  new time/op  delta
SearchInts-8  20.3ns ± 1%  16.6ns ± 6%  -18.37%  (p=0.000 n=9+10)

Change-Id: I346e5955fd6df6ce10254b22267dbc8d5a2b16c0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279439
Reviewed-by: Ben Shi <powerman1st@163.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
Trust: Robert Griesemer <gri@golang.org>
This commit is contained in:
yangwenmai 2020-12-25 09:36:41 +08:00 committed by Robert Griesemer
parent f113e9a14f
commit 7af821a661
5 changed files with 30 additions and 6 deletions

View File

@ -540,7 +540,7 @@ func searchInts(a []int, x int) int {
// TODO(gri): Remove this when compilers have caught up. // TODO(gri): Remove this when compilers have caught up.
i, j := 0, len(a) i, j := 0, len(a)
for i < j { for i < j {
h := i + (j-i)/2 // avoid overflow when computing h h := i + (j-i)>>1 // avoid overflow when computing h
// i ≤ h < j // i ≤ h < j
if a[h] <= x { if a[h] <= x {
i = h + 1 i = h + 1

View File

@ -0,0 +1,24 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package token
import (
"testing"
)
func BenchmarkSearchInts(b *testing.B) {
data := make([]int, 10000)
for i := 0; i < 10000; i++ {
data[i] = i
}
const x = 8
if r := searchInts(data, x); r != x {
b.Errorf("got index = %d; want %d", r, x)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
searchInts(data, x)
}
}

View File

@ -1723,7 +1723,7 @@ func typesByString(s string) []*rtype {
// This is a copy of sort.Search, with f(h) replaced by (*typ[h].String() >= s). // This is a copy of sort.Search, with f(h) replaced by (*typ[h].String() >= s).
i, j := 0, len(offs) i, j := 0, len(offs)
for i < j { for i < j {
h := i + (j-i)/2 // avoid overflow when computing h h := i + (j-i)>>1 // avoid overflow when computing h
// i ≤ h < j // i ≤ h < j
if !(rtypeOff(section, offs[h]).String() >= s) { if !(rtypeOff(section, offs[h]).String() >= s) {
i = h + 1 // preserves f(i-1) == false i = h + 1 // preserves f(i-1) == false

View File

@ -37,7 +37,7 @@ var (
func bsearch16(a []uint16, x uint16) int { func bsearch16(a []uint16, x uint16) int {
i, j := 0, len(a) i, j := 0, len(a)
for i < j { for i < j {
h := i + (j-i)/2 h := i + (j-i)>>1
if a[h] < x { if a[h] < x {
i = h + 1 i = h + 1
} else { } else {
@ -52,7 +52,7 @@ func bsearch16(a []uint16, x uint16) int {
func bsearch32(a []uint32, x uint32) int { func bsearch32(a []uint32, x uint32) int {
i, j := 0, len(a) i, j := 0, len(a)
for i < j { for i < j {
h := i + (j-i)/2 h := i + (j-i)>>1
if a[h] < x { if a[h] < x {
i = h + 1 i = h + 1
} else { } else {

View File

@ -440,7 +440,7 @@ func Unquote(s string) (string, error) {
func bsearch16(a []uint16, x uint16) int { func bsearch16(a []uint16, x uint16) int {
i, j := 0, len(a) i, j := 0, len(a)
for i < j { for i < j {
h := i + (j-i)/2 h := i + (j-i)>>1
if a[h] < x { if a[h] < x {
i = h + 1 i = h + 1
} else { } else {
@ -455,7 +455,7 @@ func bsearch16(a []uint16, x uint16) int {
func bsearch32(a []uint32, x uint32) int { func bsearch32(a []uint32, x uint32) int {
i, j := 0, len(a) i, j := 0, len(a)
for i < j { for i < j {
h := i + (j-i)/2 h := i + (j-i)>>1
if a[h] < x { if a[h] < x {
i = h + 1 i = h + 1
} else { } else {