1
0
mirror of https://github.com/golang/go synced 2024-11-21 22:24:40 -07:00

exp/norm: performance improvements of quickSpan

- fixed performance bug that could lead to O(n^2) behavior
- performance improvement for ASCII case

R=r, r
CC=golang-dev
https://golang.org/cl/4956060
This commit is contained in:
Marcel van Lohuizen 2011-09-05 19:09:20 +02:00
parent c7f6f9f318
commit d5e24b6975
2 changed files with 25 additions and 7 deletions

View File

@ -198,12 +198,16 @@ func (f Form) QuickSpan(b []byte) int {
func quickSpan(fd *formInfo, b []byte) int { func quickSpan(fd *formInfo, b []byte) int {
var lastCC uint8 var lastCC uint8
var lastSegStart int var lastSegStart int
i := 0 var i, nc int
for i < len(b) { for i < len(b) {
if b[i] < utf8.RuneSelf { if b[i] < utf8.RuneSelf {
lastSegStart = i // Keep the loop tight for ASCII processing, as this is where
i++ // most of the time is spent for this case.
for i++; i < len(b) && b[i] < utf8.RuneSelf; i++ {
}
lastSegStart = i - 1
lastCC = 0 lastCC = 0
nc = 0
continue continue
} }
info := fd.info(b[i:]) info := fd.info(b[i:])
@ -212,9 +216,6 @@ func quickSpan(fd *formInfo, b []byte) int {
return len(b) return len(b)
} }
cc := info.ccc cc := info.ccc
if lastCC > cc && cc != 0 {
return lastSegStart
}
if fd.composing { if fd.composing {
if !info.flags.isYesC() { if !info.flags.isYesC() {
break break
@ -224,8 +225,20 @@ func quickSpan(fd *formInfo, b []byte) int {
break break
} }
} }
if !fd.composing && cc == 0 { if cc == 0 {
lastSegStart = i lastSegStart = i
nc = 0
} else {
if nc >= maxCombiningChars {
lastSegStart = i
lastCC = cc
nc = 1
} else {
if lastCC > cc {
return lastSegStart
}
nc++
}
} }
lastCC = cc lastCC = cc
i += int(info.size) i += int(info.size)

View File

@ -220,6 +220,11 @@ var quickSpanTests = []PositionTest{
// incorrectly ordered combining characters // incorrectly ordered combining characters
{"\u0300\u0316", 0, ""}, {"\u0300\u0316", 0, ""},
{"\u0300\u0316cd", 0, ""}, {"\u0300\u0316cd", 0, ""},
// have a maximum number of combining characters.
{strings.Repeat("\u035D", 30) + "\u035B", 62, ""},
{"a" + strings.Repeat("\u035D", 30) + "\u035B", 63, ""},
{"Ɵ" + strings.Repeat("\u035D", 30) + "\u035B", 64, ""},
{"aa" + strings.Repeat("\u035D", 30) + "\u035B", 64, ""},
} }
var quickSpanNFDTests = []PositionTest{ var quickSpanNFDTests = []PositionTest{