Чтобы уменьшить буфер сканера 64k по умолчанию (для микрокомпьютера с малой памятью), я пытаюсь использовать этот буфер и пользовательские функции разделения:
scanner.Buffer(make([]byte, 5120), 64)
scanner.Split(Scan64Bytes)
Здесь я заметил, что второй аргумент буфера «max» не действует. Если я вместо этого вставлю, например. 0, 1, 5120 или bufio.MaxScanTokenSize, разницы не вижу. Только первый аргумент "буф" имеет последствия. Если емкость мала, сканирование будет неполным, а если она слишком велика, значение B/op Benchmem увеличится.
Из документа:
The maximum token size is the larger of max and cap(buf). If max <= cap(buf), Scan will use this buffer only and do no allocation.
Я не понимаю, что является правильным максимальным значением. Может быть, вы можете объяснить мне это, пожалуйста?
package main
import (
"bufio"
"bytes"
"fmt"
)
func Scan64Bytes(data []byte, atEOF bool) (advance int, token []byte, err error) {
if len(data) < 64 {
return 0, data[0:], bufio.ErrFinalToken
}
return 64, data[0:64], nil
}
func main() {
// improvised source of the same size:
cmdstd := bytes.NewReader(make([]byte, 5120))
scanner := bufio.NewScanner(cmdstd)
// I guess 64 is the correct max arg:
scanner.Buffer(make([]byte, 5120), 64)
scanner.Split(Scan64Bytes)
for i := 0; scanner.Scan(); i++ {
fmt.Printf("%v: %v\r\n", i, scanner.Bytes())
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
}
}
Я инициализировал наименьший возможный буфер для проекта, чтобы сэкономить ресурсы, и 64 байта считываются на строку/токен. Я совершенно не уверен в требуемом значении «max». Может дело в переводе... Я совсем запутался.
Я не знаю, чего вы ожидаете, когда начинаете с 5120-байтового буфера, но хотите каким-то образом ограничить его до 64 байт. Независимо от размера буфера поведение сканера будет одинаковым. Просто закончите писать код и позаботьтесь об оптимизации использования памяти позже.
Это означает, что я мог бы с самого начала установить значение scanner.Buffer(make([]byte, 5120), 5120)
? Мой микрокомпьютер имеет только ограниченную свободную память и нуждается в подкачке для некоторых задач.
Это не имеет значения. В документах, которые вы цитируете, конкретно говорится, что если max меньше или равен размеру буфера, он не будет выделять больше.
@JimB Спасибо за вашу помощь и время. Теперь я наконец понял :-)
max value has no effect on custom Split?
Нет, без разделения результат тот же. Но это было бы невозможно без разделения и ErrFinalToken:
//your reader/input
cmdstd := bytes.NewReader(make([]byte, 5120))
// your scanner buffer size
scanner.Buffer(make([]byte, 5120), 64)
Размер буфера от сканера должен быть больше. Вот как я бы установил buf и max:
scanner.Buffer(make([]byte, 5121), 5120)
Большое спасибо, что указали на это scanner.Buffer
должен >bytes.NewReader
. И ваш полезный пример со значением «max».
Начальный буфер и максимальный размер влияют только на используемую буферизованную память. Что вы ожидаете от него?