summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2017-08-26 01:28:39 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2017-08-26 01:28:39 +0900
commit71fdb99a07cbb05e5cea4050abb56df2013898f9 (patch)
tree4aad848ce6ff7910293d02901bdf35167d940b22
parent55ee4186aa688e524e041971d588a6f002486deb (diff)
Remove bound checkings in inner loops
-rw-r--r--src/algo/algo.go92
1 files changed, 54 insertions, 38 deletions
diff --git a/src/algo/algo.go b/src/algo/algo.go
index 6498ae8c..433b8da2 100644
--- a/src/algo/algo.go
+++ b/src/algo/algo.go
@@ -328,7 +328,11 @@ func debugV2(T []rune, pattern []rune, F []int32, lastIdx int, H []int16, C []in
if idx+int(F[0]) < int(F[i]) {
p = 0
}
- fmt.Printf("%2d ", p)
+ if p > 0 {
+ fmt.Printf("%2d ", p)
+ } else {
+ fmt.Print(" ")
+ }
}
fmt.Println()
}
@@ -373,8 +377,10 @@ func FuzzyMatchV2(caseSensitive bool, normalize bool, forward bool, input *util.
// Phase 2. Calculate bonus for each point
maxScore, maxScorePos := int16(0), 0
pidx, lastIdx := 0, 0
- for pchar0, prevClass, inGap := pattern[0], charNonWord, false; idx < N; idx++ {
- char := T[idx]
+ pchar0, pchar, prevH0, prevClass, inGap := pattern[0], pattern[0], int16(0), charNonWord, false
+ Tsub := T[idx:]
+ H0sub, C0sub, Bsub := H0[idx:][:len(Tsub)], C0[idx:][:len(Tsub)], B[idx:][:len(Tsub)]
+ for off, char := range Tsub {
var class charClass
if char <= unicode.MaxASCII {
class = charClassOfAscii(char)
@@ -394,41 +400,41 @@ func FuzzyMatchV2(caseSensitive bool, normalize bool, forward bool, input *util.
char = normalizeRune(char)
}
- T[idx] = char
+ Tsub[off] = char
bonus := bonusFor(prevClass, class)
- B[idx] = bonus
+ Bsub[off] = bonus
prevClass = class
- if char == pattern[util.Min(pidx, M-1)] {
+ if char == pchar {
if pidx < M {
- F[pidx] = int32(idx)
+ F[pidx] = int32(idx + off)
pidx++
+ pchar = pattern[util.Min(pidx, M-1)]
}
- lastIdx = idx
+ lastIdx = idx + off
}
if char == pchar0 {
score := scoreMatch + bonus*bonusFirstCharMultiplier
- H0[idx] = score
- C0[idx] = 1
+ H0sub[off] = score
+ C0sub[off] = 1
if M == 1 && (forward && score > maxScore || !forward && score >= maxScore) {
- maxScore, maxScorePos = score, idx
+ maxScore, maxScorePos = score, idx+off
if forward && bonus == bonusBoundary {
break
}
}
inGap = false
} else {
- if idx == 0 {
- H0[idx] = 0
- } else if inGap {
- H0[idx] = util.Max16(H0[idx-1]+scoreGapExtention, 0)
+ if inGap {
+ H0sub[off] = util.Max16(prevH0+scoreGapExtention, 0)
} else {
- H0[idx] = util.Max16(H0[idx-1]+scoreGapStart, 0)
+ H0sub[off] = util.Max16(prevH0+scoreGapStart, 0)
}
- C0[idx] = 0
+ C0sub[off] = 0
inGap = true
}
+ prevH0 = H0sub[off]
}
if pidx != M {
return Result{-1, -1, 0}, nil
@@ -453,47 +459,57 @@ func FuzzyMatchV2(caseSensitive bool, normalize bool, forward bool, input *util.
offset16, C := alloc16(offset16, slab, width*M)
copy(C, C0[f0:lastIdx+1])
- for i := 1; i < M; i++ {
- I := i * width
- f := int(F[i])
+ Fsub := F[1:]
+ Psub := pattern[1:][:len(Fsub)]
+ for off, f := range Fsub {
+ f := int(f)
+ pchar := Psub[off]
+ pidx := off + 1
+ row := pidx * width
inGap := false
- for j := f; j <= lastIdx; j++ {
- j0 := j - f0
+ Tsub := T[f : lastIdx+1]
+ Bsub := B[f:][:len(Tsub)]
+ Csub := C[row+f-f0:][:len(Tsub)]
+ Cdiag := C[row+f-f0-1-width:][:len(Tsub)]
+ Hsub := H[row+f-f0:][:len(Tsub)]
+ Hdiag := H[row+f-f0-1-width:][:len(Tsub)]
+ Hleft := H[row+f-f0-1:][:len(Tsub)]
+ Hleft[0] = 0
+ for off, char := range Tsub {
+ col := off + f
var s1, s2, consecutive int16
- if j > f {
- if inGap {
- s2 = H[I+j0-1] + scoreGapExtention
- } else {
- s2 = H[I+j0-1] + scoreGapStart
- }
+ if inGap {
+ s2 = Hleft[off] + scoreGapExtention
+ } else {
+ s2 = Hleft[off] + scoreGapStart
}
- if pattern[i] == T[j] {
- s1 = H[I-width+j0-1] + scoreMatch
- b := B[j]
- consecutive = C[I-width+j0-1] + 1
+ if pchar == char {
+ s1 = Hdiag[off] + scoreMatch
+ b := Bsub[off]
+ consecutive = Cdiag[off] + 1
// Break consecutive chunk
if b == bonusBoundary {
consecutive = 1
} else if consecutive > 1 {
- b = util.Max16(b, util.Max16(bonusConsecutive, B[j-int(consecutive)+1]))
+ b = util.Max16(b, util.Max16(bonusConsecutive, B[col-int(consecutive)+1]))
}
if s1+b < s2 {
- s1 += B[j]
+ s1 += Bsub[off]
consecutive = 0
} else {
s1 += b
}
}
- C[I+j0] = consecutive
+ Csub[off] = consecutive
inGap = s1 < s2
score := util.Max16(util.Max16(s1, s2), 0)
- if i == M-1 && (forward && score > maxScore || !forward && score >= maxScore) {
- maxScore, maxScorePos = score, j
+ if pidx == M-1 && (forward && score > maxScore || !forward && score >= maxScore) {
+ maxScore, maxScorePos = score, col
}
- H[I+j0] = score
+ Hsub[off] = score
}
}