mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2024-12-23 03:19:01 +00:00
Improve ingestion performance (by around 40%)
Summary fzf --sync --bind load:accept < 27M-lines ran 1.16 ± 0.01 times faster than fzf-41b3511 --sync --bind load:accept < 27M-lines 1.44 ± 0.01 times faster than fzf-0.48.1 --sync --bind load:accept < 27M-lines
This commit is contained in:
parent
41b3511ad9
commit
5234c3759a
@ -3,7 +3,7 @@ CHANGELOG
|
|||||||
|
|
||||||
0.49.0
|
0.49.0
|
||||||
------
|
------
|
||||||
- Ingestion performance improved by around 20%
|
- Ingestion performance improved by around 40%
|
||||||
- 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`
|
||||||
|
139
src/reader.go
139
src/reader.go
@ -1,13 +1,12 @@
|
|||||||
package fzf
|
package fzf
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@ -112,86 +111,82 @@ func (r *Reader) ReadSource(root string, opts walkerOpts, ignores []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Reader) feed(src io.Reader) {
|
func (r *Reader) feed(src io.Reader) {
|
||||||
readerSlabSize, ae := strconv.Atoi(os.Getenv("SLAB_KB"))
|
/*
|
||||||
if ae != nil {
|
readerSlabSize, ae := strconv.Atoi(os.Getenv("SLAB_KB"))
|
||||||
readerSlabSize = 128 * 1024
|
if ae != nil {
|
||||||
} else {
|
readerSlabSize = 128 * 1024
|
||||||
readerSlabSize *= 1024
|
} else {
|
||||||
}
|
readerSlabSize *= 1024
|
||||||
readerBufferSize, be := strconv.Atoi(os.Getenv("BUF_KB"))
|
}
|
||||||
if be != nil {
|
readerBufferSize, be := strconv.Atoi(os.Getenv("BUF_KB"))
|
||||||
readerBufferSize = 64 * 1024
|
if be != nil {
|
||||||
} else {
|
readerBufferSize = 64 * 1024
|
||||||
readerBufferSize *= 1024
|
} else {
|
||||||
}
|
readerBufferSize *= 1024
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
slab := make([]byte, readerSlabSize)
|
|
||||||
pointer := 0
|
|
||||||
delim := byte('\n')
|
delim := byte('\n')
|
||||||
if r.delimNil {
|
if r.delimNil {
|
||||||
delim = '\000'
|
delim = '\000'
|
||||||
}
|
}
|
||||||
reader := bufio.NewReaderSize(src, readerBufferSize)
|
|
||||||
|
|
||||||
// We do not put a slice longer than 10% of the slab to reduce fragmentation
|
|
||||||
maxBytes := readerBufferSize / 10
|
|
||||||
|
|
||||||
|
slab := make([]byte, readerSlabSize)
|
||||||
|
leftover := []byte{}
|
||||||
|
var err error
|
||||||
for {
|
for {
|
||||||
var frags [][]byte
|
n := 0
|
||||||
fragsLen := 0
|
scope := slab[:util.Min(len(slab), readerBufferSize)]
|
||||||
for {
|
for i := 0; i < 100; i++ {
|
||||||
bytea, err := reader.ReadSlice(delim)
|
n, err = src.Read(scope)
|
||||||
if err == bufio.ErrBufferFull {
|
if n > 0 || err != nil {
|
||||||
// Could not find the delimiter in the reader buffer.
|
|
||||||
// Need to collect the fragments and merge them later.
|
|
||||||
frags = append(frags, bytea)
|
|
||||||
fragsLen += len(bytea)
|
|
||||||
} else {
|
|
||||||
byteaLen := len(bytea)
|
|
||||||
if err == nil {
|
|
||||||
// No errors. Found the delimiter.
|
|
||||||
if util.IsWindows() && byteaLen >= 2 && bytea[byteaLen-2] == byte('\r') {
|
|
||||||
bytea = bytea[:byteaLen-2]
|
|
||||||
byteaLen -= 2
|
|
||||||
} else {
|
|
||||||
bytea = bytea[:byteaLen-1]
|
|
||||||
byteaLen--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
itemLen := fragsLen + byteaLen
|
|
||||||
pointer += itemLen
|
|
||||||
var slice []byte
|
|
||||||
if itemLen <= maxBytes { // We can use the slab
|
|
||||||
// Allocate a new slab if it doesn't fit
|
|
||||||
if pointer > readerSlabSize {
|
|
||||||
slab = make([]byte, readerSlabSize)
|
|
||||||
pointer = itemLen
|
|
||||||
}
|
|
||||||
slice = slab[pointer-itemLen : pointer]
|
|
||||||
} else { // We can't use the slab because the item is too large
|
|
||||||
slice = make([]byte, itemLen)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(frags) > 0 {
|
|
||||||
// Collect the fragments
|
|
||||||
n := 0
|
|
||||||
for _, frag := range frags {
|
|
||||||
n += copy(slice[n:], frag)
|
|
||||||
}
|
|
||||||
copy(slice[n:], bytea)
|
|
||||||
} else if byteaLen > 0 {
|
|
||||||
copy(slice, bytea)
|
|
||||||
}
|
|
||||||
if (err == nil || itemLen > 0) && r.pusher(slice) {
|
|
||||||
atomic.StoreInt32(&r.event, int32(EvtReadNew))
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We're not making any progress after 100 tries. Stop.
|
||||||
|
if n == 0 && err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := slab[:n]
|
||||||
|
slab = slab[n:]
|
||||||
|
|
||||||
|
for len(buf) > 0 {
|
||||||
|
if i := bytes.IndexByte(buf, delim); i >= 0 {
|
||||||
|
// Found the delimiter
|
||||||
|
slice := buf[:i+1]
|
||||||
|
buf = buf[i+1:]
|
||||||
|
if util.IsWindows() && len(slice) >= 2 && slice[len(slice)-2] == byte('\r') {
|
||||||
|
slice = slice[:len(slice)-2]
|
||||||
|
} else {
|
||||||
|
slice = slice[:len(slice)-1]
|
||||||
|
}
|
||||||
|
if len(leftover) > 0 {
|
||||||
|
slice = append(leftover, slice...)
|
||||||
|
leftover = []byte{}
|
||||||
|
}
|
||||||
|
if (err == nil || len(slice) > 0) && r.pusher(slice) {
|
||||||
|
atomic.StoreInt32(&r.event, int32(EvtReadNew))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Could not find the delimiter in the buffer
|
||||||
|
leftover = append(leftover, buf...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == io.EOF {
|
||||||
|
leftover = append(leftover, buf...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(slab) == 0 {
|
||||||
|
slab = make([]byte, readerSlabSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(leftover) > 0 && r.pusher(leftover) {
|
||||||
|
atomic.StoreInt32(&r.event, int32(EvtReadNew))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user