Feeding Scanner.Bytes () на канал в Go - PullRequest
0 голосов
/ 08 мая 2018

Пожалуйста, рассмотрите этот скрипт: https://play.golang.org/p/o4ZhuB3GJ0s (важная часть ниже)

Он создает случайные (ish) строки, которые выглядят как «foo | foo» (где «foo» - случайный, но повторяется).

Я читаю их с Scanner.Bytes() во входной канал, затем 16 рабочих потоков преобразуют их в строки и помещают в выходной канал.

В выходном канале я разбил строки на |, чтобы убедиться, что обе стороны одинаковы (без повреждения данных).

Вот часть кода, которая сканирует входной буфер:

// Send input into channel
go func() {
    // Normally os.Stdin
    s := bufio.NewScanner(simulatedStdin)
    start = time.Now()
    for s.Scan() {
        thisLine := s.Bytes()
        line := make([]byte, len(thisLine))
        // Copy the slice so it's not changed on the next iteration
        copy(line, thisLine)
        lines <- line

        // Works, but perhaps the least efficient way to do it
        // lines <- []byte(string(s.Bytes()))
        // lines <- []byte(s.Text())

        // Fails
        // lines <- []byte(s.Bytes())
        // lines <- s.Bytes()[:]
        // lines <- s.Bytes()
    }
    close(lines)
}()

Версия выше работает правильно, но если я просто сделаю lines <- s.Bytes() (или другие, которые я протестировал), данные будут повреждены, потому что Scanner.Bytes () всегда возвращает один и тот же слайс, и я пропускаю этот слайс через канал, но он мутирует, пока рабочие его читают.

У меня вопрос: как правильно / идиоматически поставить Scanner.Bytes() на канал, чтобы предотвратить это повреждение? Способ, который я опубликовал выше, работает, но это довольно уродливо, ИМХО, и взлом строк короток, но это действительно ужасный способ копирования данных.

В конечном счете, я использую этот метод для чтения миллиардов строк данных, поэтому, если можно удалить лишнюю []byte копию, я полностью за нее. Работа на рабочих выполняется медленно (JSON Unmarshaling и т. Д.), Но сканер ввода представляет собой один поток, поэтому я стараюсь разбить его на строки как можно быстрее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...