Further performance improvements by removing unnecessary copies

pull/3707/head
Junegunn Choi 2 months ago
parent a575c0c54b
commit c30e486b64
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627

@ -3,7 +3,10 @@ CHANGELOG
0.49.0 0.49.0
------ ------
- Ingestion performance improved by around 40% - Performance improvements
- Ingestion performance improved by 40%
- `--ansi` performance improved by 50%
- `--with-nth` performance improved by 30%
- Added two environment variables exported to the child processes - Added two environment variables exported to the child processes
- `FZF_PREVIEW_LABEL` - `FZF_PREVIEW_LABEL`
- `FZF_BORDER_LABEL` - `FZF_BORDER_LABEL`

@ -312,7 +312,7 @@ func parseAnsiCode(s string, delimiter byte) (int, byte, string) {
// Inlined version of strconv.Atoi() that only handles positive // Inlined version of strconv.Atoi() that only handles positive
// integers and does not allocate on error. // integers and does not allocate on error.
code := 0 code := 0
for _, ch := range []byte(s) { for _, ch := range sbytes(s) {
ch -= '0' ch -= '0'
if ch > 9 { if ch > 9 {
return -1, delimiter, remaining return -1, delimiter, remaining

@ -23,6 +23,10 @@ func ustring(data []byte) string {
return unsafe.String(unsafe.SliceData(data), len(data)) return unsafe.String(unsafe.SliceData(data), len(data))
} }
func sbytes(data string) []byte {
return unsafe.Slice(unsafe.StringData(data), len(data))
}
// Run starts fzf // Run starts fzf
func Run(opts *Options, version string, revision string) { func Run(opts *Options, version string, revision string) {
sort := opts.Sort > 0 sort := opts.Sort > 0
@ -52,14 +56,14 @@ func Run(opts *Options, version string, revision string) {
prevLineAnsiState = lineAnsiState prevLineAnsiState = lineAnsiState
trimmed, offsets, newState := extractColor(ustring(data), lineAnsiState, nil) trimmed, offsets, newState := extractColor(ustring(data), lineAnsiState, nil)
lineAnsiState = newState lineAnsiState = newState
return util.ToChars([]byte(trimmed)), offsets return util.ToChars(sbytes(trimmed)), offsets
} }
} else { } else {
// When color is disabled but ansi option is given, // When color is disabled but ansi option is given,
// we simply strip out ANSI codes from the input // we simply strip out ANSI codes from the input
ansiProcessor = func(data []byte) (util.Chars, *[]ansiOffset) { ansiProcessor = func(data []byte) (util.Chars, *[]ansiOffset) {
trimmed, _, _ := extractColor(ustring(data), nil, nil) trimmed, _, _ := extractColor(ustring(data), nil, nil)
return util.ToChars([]byte(trimmed)), nil return util.ToChars(sbytes(trimmed)), nil
} }
} }
} }
@ -106,7 +110,7 @@ func Run(opts *Options, version string, revision string) {
eventBox.Set(EvtHeader, header) eventBox.Set(EvtHeader, header)
return false return false
} }
item.text, item.colors = ansiProcessor([]byte(transformed)) item.text, item.colors = ansiProcessor(sbytes(transformed))
item.text.TrimTrailingWhitespaces() item.text.TrimTrailingWhitespaces()
item.text.Index = itemIndex item.text.Index = itemIndex
item.origText = &data item.origText = &data

@ -91,7 +91,7 @@ func withPrefixLengths(tokens []string, begin int) []Token {
prefixLength := begin prefixLength := begin
for idx := range tokens { for idx := range tokens {
chars := util.ToChars([]byte(tokens[idx])) chars := util.ToChars(sbytes(tokens[idx]))
ret[idx] = Token{&chars, int32(prefixLength)} ret[idx] = Token{&chars, int32(prefixLength)}
prefixLength += chars.Length() prefixLength += chars.Length()
} }
@ -187,7 +187,7 @@ func Transform(tokens []Token, withNth []Range) []Token {
if r.begin == r.end { if r.begin == r.end {
idx := r.begin idx := r.begin
if idx == rangeEllipsis { if idx == rangeEllipsis {
chars := util.ToChars([]byte(joinTokens(tokens))) chars := util.ToChars(sbytes(joinTokens(tokens)))
parts = append(parts, &chars) parts = append(parts, &chars)
} else { } else {
if idx < 0 { if idx < 0 {

@ -163,7 +163,7 @@ func (chars *Chars) ToString() string {
if runes := chars.optionalRunes(); runes != nil { if runes := chars.optionalRunes(); runes != nil {
return string(runes) return string(runes)
} }
return string(chars.slice) return unsafe.String(unsafe.SliceData(chars.slice), len(chars.slice))
} }
func (chars *Chars) ToRunes() []rune { func (chars *Chars) ToRunes() []rune {

Loading…
Cancel
Save