Alexander
не знаю
Alexander
я не умею придумывать либы
Alexander
@A64m_qb0 а ты знаешь как фастбилдер работает?
Alexander
какой из них создавал pipe и сам в себя писал, это не он?
A64m
запускает какое-то мутабельное адище в отдельном потоке?
Dmitry
unsafePerformIO - вот это всё?
A64m
только вот в таких вот общих чертах
A64m
да ансейфперформ это по стандартам обычных байтстрок не адище
A64m
сами байтстроки оперируют на два круга ада ниже
Alexander
import qualified Data.ByteString.Builder.Extra as X
Alexander
он использует обычный билдер внутри
Alexander
офигенный код, я не понимаю что там происходит и где
Alexander
т.е. не могу найти где самое интересное
A64m
он точно отчасти должен работать как блейз-билдер, потому как автор очень интересовался ваншот-аннотациями, в том числе и репрезентационно-полиморфными для функций анбокснутых аргументов
A64m
но может это был тупиковый вариант, который потом под нож пошел
Alexander
ваще круто на самом деле
Alexander
я пока до конца не понимаю, но мне уже нравится
Alexander
он создает thunk = unsafeDupablePerformIO $ runBuilder
Alexander
делает evaluate, WHNF его описывает нужно ли дальше делать или все готово
Alexander
если дальше, то thunk кидается в отдельный тред который возвращает thunk для хвоста
Alexander
и отдается консьюмеру
Alexander
консьюмер сразу может работать с головой
Alexander
если же он форсит хвост, то он блокируется пока следующий чанк не будет готов
Alexander
а тред в это время в фоне генерит его и следующий
Alexander
и похоже нету хранения длины явного
Alexander
Builder тут это \DataSink -> BuilderState -> BuilderState
Alexander
как в PutM
Alexander
он же стейт над парой указателей
Alexander
-- | This datatype exists only to work around the limitation that 'oneShot' -- cannot work with unboxed argument types.
Alexander
сколько же туда работы вбухано
Alexander
@A64m_qb0 а тормозит hPutBuffer т.к. там он не делает чанки большие похоже
A64m
вот из обсуждения этой штуки в каком-то тикете на гхц-траке я про фастбилдер и узнал
Alexander
HandleSink h queueRef -> do cur <- getCur io $ flushQueue h queueRef cur io $ S.hPut h bstr
Alexander
может если вчитаться то все нормально но похоже что если мы пишем в handle то сразу вбрасываем кусочки
Alexander
ещё и через S.hPut который сделает доп write на проверку готовности и poll вначале/вконце
A64m
похоже, что во всех этой байтстринг инфраструктуре чанки делают только читатели а писатели тупо пишут какие есть
Alexander
вот тут не совсем
Alexander
тут читатель делает первый чанк
Alexander
остальные делает специально обученный тред
Alexander
я думаю при тормозном консьюмере внешнем это вообще пушка будет
Alexander
но с неограниченная по памяти
Alexander
а или я комментарий не понял?
Alexander
очень интересно, что тут билдер гораздо больше похож на PutM от которого ушли
A64m
я комментировал не билдер а обычный байтстринг-мирок
Alexander
а
Alexander
да
Alexander
это кстати проблема
Alexander
в network-transport tcp тоже вылезало
Alexander
кстати надо бы через fast-builder попробовать пофиксить
Alexander
а не network-transport-tcp более низкий
Alexander
он уже на языке [ByteString] говорит
Alexander
cloud haskell в продакшене ни у кого рядом нет? а то наш проект временно(?) без нас работает и на нём мне не померять
A64m
{-# Language OverloadedStrings #-} {-# OPTIONS_GHC -fno-warn-incomplete-patterns #-} module Main where import qualified Data.ByteString.Char8 as BS8 import qualified Data.ByteString.Lazy as BSL import qualified Data.ByteString.FastBuilder as Builder import Data.ByteString.Char8 (ByteString) import Data.Monoid ((<>)) import qualified Data.Vector as V import GHC.Exts import System.IO main :: IO () main = do ws <- BS8.lines <$> BS8.getContents let s = V.map (\v -> case BS8.words v of (a:_) -> a) $ V.fromList ws BSL.hPutStr stdout $ Builder.toLazyByteStringWith 110000 110000 $ foldMap (\suff -> V.foldr (\pref nx -> Builder.byteString suff <> Builder.byteString pref <> Builder.char8 '\n' <> nx) mempty (mkP ws)) s {-# NOINLINE mkP #-} mkP = V.map (\v -> case BS8.words v of (_:b:_) -> b) . V.fromList
кана
подскажите, в чем прикол использовать кейс в таком виде вместо let case xs of (x:_) -> x let x:_ = xs in x
кана
или даже просто head. Строгость? Потому что тут огромная лямбда заменяется на красивое head . BS8.words
分解物質
@yellow_apple ^ формально может неудачно получиться как раз на границе
я об этом изначально знал но решил забить уже профиксил
Ilya
а что там за разделители строк во входном файле?
Dmitry
\s+
Ilya
это что?
Ilya
просто у меня хэши не совпадают с референсной версией, боюсь из-за этого как раз
Ilya
смотрю - строки длиннее на один байт, чем у меня
Dmitry
в смысле? хэш ведь для выхлопа проверяется
Dmitry
какая разница, что там на входе
Ilya
ща поясню
Dmitry
выход - строки разделяются \n
Ilya
есть ваша референсная прога, которая pypy
Ilya
и есть моя
Ilya
вывод у них внешне одинаковый, но хэши разные
Dmitry
\r
Dmitry
убери в таком случае
Aragaer
во входном файле разделители строк \r\n, но могут быть просто \n
Aragaer
в выходном должно быть \n
Ilya
\r
во, видимо в этом дело
Ilya
причём даже vim с :set list разницы не видит
Dmitry
референсная, кстати не наша
Dmitry
референсная из исходного наброса
Ilya
но прогнал через xxd и увидел, что строки на один байт длиннее
Ilya
референсная, кстати не наша
ща будет ускоренная версия на pypy