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
分解物質
Ilya
а что там за разделители строк во входном файле?
Dmitry
\s+
Ilya
это что?
Ilya
просто у меня хэши не совпадают с референсной версией, боюсь из-за этого как раз
Ilya
смотрю - строки длиннее на один байт, чем у меня
Alexander
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 и увидел, что строки на один байт длиннее