mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2024-11-18 02:55:11 +00:00
Improve search performance by pre-calculating character classes
This simple optmization can give more than 15% performance boost in some scenarios.
This commit is contained in:
parent
5643a306bd
commit
7ce6452d83
@ -153,6 +153,9 @@ var (
|
|||||||
bonusBoundaryDelimiter int16 = bonusBoundary + 1
|
bonusBoundaryDelimiter int16 = bonusBoundary + 1
|
||||||
|
|
||||||
initialCharClass charClass = charWhite
|
initialCharClass charClass = charWhite
|
||||||
|
|
||||||
|
// A minor optimization that can give 15%+ performance boost
|
||||||
|
asciiCharClasses [unicode.MaxASCII + 1]charClass
|
||||||
)
|
)
|
||||||
|
|
||||||
type charClass int
|
type charClass int
|
||||||
@ -187,6 +190,22 @@ func Init(scheme string) bool {
|
|||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
for i := 0; i <= unicode.MaxASCII; i++ {
|
||||||
|
char := rune(i)
|
||||||
|
c := charNonWord
|
||||||
|
if char >= 'a' && char <= 'z' {
|
||||||
|
c = charLower
|
||||||
|
} else if char >= 'A' && char <= 'Z' {
|
||||||
|
c = charUpper
|
||||||
|
} else if char >= '0' && char <= '9' {
|
||||||
|
c = charNumber
|
||||||
|
} else if strings.ContainsRune(whiteChars, char) {
|
||||||
|
c = charWhite
|
||||||
|
} else if strings.ContainsRune(delimiterChars, char) {
|
||||||
|
c = charDelimiter
|
||||||
|
}
|
||||||
|
asciiCharClasses[i] = c
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,21 +233,6 @@ func alloc32(offset int, slab *util.Slab, size int) (int, []int32) {
|
|||||||
return offset, make([]int32, size)
|
return offset, make([]int32, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
func charClassOfAscii(char rune) charClass {
|
|
||||||
if char >= 'a' && char <= 'z' {
|
|
||||||
return charLower
|
|
||||||
} else if char >= 'A' && char <= 'Z' {
|
|
||||||
return charUpper
|
|
||||||
} else if char >= '0' && char <= '9' {
|
|
||||||
return charNumber
|
|
||||||
} else if strings.ContainsRune(whiteChars, char) {
|
|
||||||
return charWhite
|
|
||||||
} else if strings.ContainsRune(delimiterChars, char) {
|
|
||||||
return charDelimiter
|
|
||||||
}
|
|
||||||
return charNonWord
|
|
||||||
}
|
|
||||||
|
|
||||||
func charClassOfNonAscii(char rune) charClass {
|
func charClassOfNonAscii(char rune) charClass {
|
||||||
if unicode.IsLower(char) {
|
if unicode.IsLower(char) {
|
||||||
return charLower
|
return charLower
|
||||||
@ -248,7 +252,7 @@ func charClassOfNonAscii(char rune) charClass {
|
|||||||
|
|
||||||
func charClassOf(char rune) charClass {
|
func charClassOf(char rune) charClass {
|
||||||
if char <= unicode.MaxASCII {
|
if char <= unicode.MaxASCII {
|
||||||
return charClassOfAscii(char)
|
return asciiCharClasses[char]
|
||||||
}
|
}
|
||||||
return charClassOfNonAscii(char)
|
return charClassOfNonAscii(char)
|
||||||
}
|
}
|
||||||
@ -447,9 +451,10 @@ func FuzzyMatchV2(caseSensitive bool, normalize bool, forward bool, input *util.
|
|||||||
for off, char := range Tsub {
|
for off, char := range Tsub {
|
||||||
var class charClass
|
var class charClass
|
||||||
if char <= unicode.MaxASCII {
|
if char <= unicode.MaxASCII {
|
||||||
class = charClassOfAscii(char)
|
class = asciiCharClasses[char]
|
||||||
if !caseSensitive && class == charUpper {
|
if !caseSensitive && class == charUpper {
|
||||||
char += 32
|
char += 32
|
||||||
|
Tsub[off] = char
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
class = charClassOfNonAscii(char)
|
class = charClassOfNonAscii(char)
|
||||||
@ -459,9 +464,9 @@ func FuzzyMatchV2(caseSensitive bool, normalize bool, forward bool, input *util.
|
|||||||
if normalize {
|
if normalize {
|
||||||
char = normalizeRune(char)
|
char = normalizeRune(char)
|
||||||
}
|
}
|
||||||
|
Tsub[off] = char
|
||||||
}
|
}
|
||||||
|
|
||||||
Tsub[off] = char
|
|
||||||
bonus := bonusFor(prevClass, class)
|
bonus := bonusFor(prevClass, class)
|
||||||
Bsub[off] = bonus
|
Bsub[off] = bonus
|
||||||
prevClass = class
|
prevClass = class
|
||||||
|
@ -9,6 +9,10 @@ import (
|
|||||||
"github.com/junegunn/fzf/src/util"
|
"github.com/junegunn/fzf/src/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Init("default")
|
||||||
|
}
|
||||||
|
|
||||||
func assertMatch(t *testing.T, fun Algo, caseSensitive, forward bool, input, pattern string, sidx int, eidx int, score int) {
|
func assertMatch(t *testing.T, fun Algo, caseSensitive, forward bool, input, pattern string, sidx int, eidx int, score int) {
|
||||||
assertMatch2(t, fun, caseSensitive, false, forward, input, pattern, sidx, eidx, score)
|
assertMatch2(t, fun, caseSensitive, false, forward, input, pattern, sidx, eidx, score)
|
||||||
}
|
}
|
||||||
|
@ -2259,9 +2259,7 @@ func postProcessOptions(opts *Options) {
|
|||||||
theme.Spinner = boldify(theme.Spinner)
|
theme.Spinner = boldify(theme.Spinner)
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Scheme != "default" {
|
|
||||||
processScheme(opts)
|
processScheme(opts)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func expectsArbitraryString(opt string) bool {
|
func expectsArbitraryString(opt string) bool {
|
||||||
|
Loading…
Reference in New Issue
Block a user