mirror of
https://github.com/golang/go
synced 2024-09-30 17:38:33 -06:00
strings: use Index in Count
This simplifies code and provides performance iprovments: Similar to https://go-review.googlesource.com/#/c/28577 CountHard1-48 1.74ms ±14% 0.17ms ±14% -90.16% (p=0.000 n=19+19) CountHard2-48 1.78ms ±15% 0.25ms ±13% -86.10% (p=0.000 n=19+20) CountHard3-48 1.78ms ±12% 0.80ms ±11% -55.19% (p=0.000 n=17+20) CountTorture-48 13.5µs ±14% 13.6µs ±11% ~ (p=0.625 n=18+19) CountTortureOverlapping-48 6.92ms ±13% 8.42ms ±11% +21.72% (p=0.000 n=19+17) Change-Id: Ief120aee918a66487c76be56e0796871c8502f89 Reviewed-on: https://go-review.googlesource.com/28586 Run-TryBot: Ilya Tocar <ilya.tocar@intel.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
86b2f29676
commit
6347367be3
@ -77,48 +77,18 @@ func hashStrRev(sep string) (uint32, uint32) {
|
|||||||
func Count(s, sep string) int {
|
func Count(s, sep string) int {
|
||||||
n := 0
|
n := 0
|
||||||
// special cases
|
// special cases
|
||||||
switch {
|
if len(sep) == 0 {
|
||||||
case len(sep) == 0:
|
|
||||||
return utf8.RuneCountInString(s) + 1
|
return utf8.RuneCountInString(s) + 1
|
||||||
case len(sep) == 1:
|
|
||||||
// special case worth making fast
|
|
||||||
c := sep[0]
|
|
||||||
for i := 0; i < len(s); i++ {
|
|
||||||
if s[i] == c {
|
|
||||||
n++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
case len(sep) > len(s):
|
|
||||||
return 0
|
|
||||||
case len(sep) == len(s):
|
|
||||||
if sep == s {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
// Rabin-Karp search
|
offset := 0
|
||||||
hashsep, pow := hashStr(sep)
|
for {
|
||||||
h := uint32(0)
|
i := Index(s[offset:], sep)
|
||||||
for i := 0; i < len(sep); i++ {
|
if i == -1 {
|
||||||
h = h*primeRK + uint32(s[i])
|
return n
|
||||||
}
|
}
|
||||||
lastmatch := 0
|
|
||||||
if h == hashsep && s[:len(sep)] == sep {
|
|
||||||
n++
|
n++
|
||||||
lastmatch = len(sep)
|
offset += i + len(sep)
|
||||||
}
|
}
|
||||||
for i := len(sep); i < len(s); {
|
|
||||||
h *= primeRK
|
|
||||||
h += uint32(s[i])
|
|
||||||
h -= pow * uint32(s[i-len(sep)])
|
|
||||||
i++
|
|
||||||
if h == hashsep && lastmatch <= i-len(sep) && s[i-len(sep):i] == sep {
|
|
||||||
n++
|
|
||||||
lastmatch = i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contains reports whether substr is within s.
|
// Contains reports whether substr is within s.
|
||||||
|
Loading…
Reference in New Issue
Block a user