Scanner.Buffer - максимальное значение не влияет на пользовательский Split?

Чтобы уменьшить буфер сканера 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)
    }
}

Начальный буфер и максимальный размер влияют только на используемую буферизованную память. Что вы ожидаете от него?

JimB 08.04.2022 23:52

Я инициализировал наименьший возможный буфер для проекта, чтобы сэкономить ресурсы, и 64 байта считываются на строку/токен. Я совершенно не уверен в требуемом значении «max». Может дело в переводе... Я совсем запутался.

Ganso 09.04.2022 00:49

Я не знаю, чего вы ожидаете, когда начинаете с 5120-байтового буфера, но хотите каким-то образом ограничить его до 64 байт. Независимо от размера буфера поведение сканера будет одинаковым. Просто закончите писать код и позаботьтесь об оптимизации использования памяти позже.

JimB 09.04.2022 00:56

Это означает, что я мог бы с самого начала установить значение scanner.Buffer(make([]byte, 5120), 5120)? Мой микрокомпьютер имеет только ограниченную свободную память и нуждается в подкачке для некоторых задач.

Ganso 09.04.2022 01:22

Это не имеет значения. В документах, которые вы цитируете, конкретно говорится, что если max меньше или равен размеру буфера, он не будет выделять больше.

JimB 09.04.2022 13:49

@JimB Спасибо за вашу помощь и время. Теперь я наконец понял :-)

Ganso 10.04.2022 01:07
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
2
6
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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».

Ganso 10.04.2022 01:04

Другие вопросы по теме